Msys 的目的是提供一个最小的准“*nix”(即非 POSIX)Bourne Shell(一个“*nix”命令行解释器),在其中执行程序、命令和 shell 脚本就像在“* nix”系统(参考http://www.mingw.org/)。如果出于某种原因,希望从 MS Windows 命令行解释器 (cmd.exe) 运行 MinGW/bin和Msys/1.0/bin 可执行文件,则 MS Windows 环境 %PATH% 变量必须包含这两个“bin”的路径" 子目录 -- 例如 ".;C:\MinGW\bin;C:\MinGW\msys\1.0\bin;%PATH%"。
以下信息严格指使用 MinGW 提供的 GCC 4.6.2 编译器套件从通过 msys.bat 调用的 Msys sh.exe 中构建 ATLAS 库。
确保您的 Msys $PATH 环境变量包含“.:您的 MinGW 和 Msys bin 目录的路径”——即“.:/C/MinGW/bin:/C/MinGW/msys/1.0/bin:$PATH”如果那是你安装 MinGW 和 Msys 的地方(这应该在 sh 登录发生时由 /etc/profile 脚本完成,如 \msys\1.0\msys.bat 文件)。
必须对使用 system() 函数调用 shell 命令或可执行文件(“make”除外)的任何 ATLAS 程序语句进行以下更改:
1) 将“./executable”更改为“.\\executable”或“executable”,因为 MS Windows cmd.exe shell(或更准确地说,称为 MS Windows 系统库例程)将“./executable”解释为可执行文件' 。带有命令选项'/executable',因此错误消息:“'。' 未被识别为内部或外部命令、可运行程序或批处理文件。” 确保使用“-v 2”调用 ATLAS/configure 以定位任何有问题的 system() 调用——只有少数!!!
ATLAS/bin/atlas_install.c
ATLAS/CONFIG/src/atlbench.c
ATLAS/CONFIG/src/config.c
ATLAS/tune/blas/gemm/userindex.c
ATLAS/tune/blas/ger/r1search.c
ATLAS/tune/sysinfo/emit_buildinfo.c
2) 将“command ; command”更改为“command && command”,因为 MS Windows cmd.exe 不接受使用 ';' 的复合命令语句 与其他“*nix”外壳或“make”中的分隔符。
3) 用双引号将任何出现的单引号替换为 sprintf() 语句中用于传递给 system() 调用的命令的分隔字符串格式说明符;特别是在 ATLAS/CONFIG/src/config.c 文件的 SpewItForth 函数中。例如,将 "... '%s' ..." 更改为 "... \"%s\" ..."。对于使用 system() 调用调用的“make”命令,这不是必需的。由于 MS Windows cmd.exe shell 需要 CRLF 行尾终止,因此必须对 ATLAS/bin/atlas_install.c 和 ATLAS/tune/sysinfo/emit_buildinfo.c 文件进行以下更改。
在 ATLAS/bin/atlas_install.c 中,第 133 行来自:
if ( (sp == NULL) || (str[0] == '\0') || (str[0] == '\n') )
至:
if ( (sp == NULL) || (str[0] == '\0') || (str[0] == '\r') || (str[0] == '\n') )
第 165 行,来自:
else if (ln[0] == '\0' || ln[0] == '\n') ch=def;
至:
else if (ln[0] == '\0' || ln[0] == '\r' || ln[0] == '\n') ch=def;
第 175 行,来自:
else if (ln[0] == '\0' || ln[0] == '\n') ch=def;
至:
else if (ln[0] == '\0' || ln[0] == '\r' || ln[0] == '\n') ch=def;
在 ATLAS/tune/sysinfo/emit_buildinfo.c 中,第 66 行来自:
for (i=0; ln[i]; i++) if (ln[i] == '"' || ln[i] == '`') ln[i] = '\'';
至:
for (i=0; ln[i]; i++) if (ln[i] == '"' || ln[i] == '`') ln[i] = '\"';
第 68 行来自:
for (i--; i >= 0 && (ln[i] == ' ' || ln[i] == '\n' || ln[i] == '\t'); i--);
至:
for (i--; i >= 0 && (ln[i] == ' ' || ln[i] == '\r' || ln[i] == '\n' || ln[i] == '\t'); i--);
此外,在 ATLAS/tune/sysinfo/emit_buildinfo.c 文件中,更改:
if (CommandOneLine("date",DATE)) strcpy(DATE, "UNKNOWN");
至:
if (CommandOneLine("date /t",DATE)) strcpy(DATE, "UNKNOWN");
因为 MS Windows cmd.exe "date" 命令将提示 "Enter the new date: (mm-dd-yy)" 并等待永远不会输入的响应。
尽管我对每个受影响的文件进行了上述更改,但遵守基本的软件工程和配置管理原则将要求将重复的代码合并到使用某种形式的“#if defined(ATL_OS_WinNT) && defined(__MINGW32__)”处理指令包装的单个过程中防止更改对在其他“*nix”操作系统上安装 ATLAS 产生不利影响。在这方面,我不建议使用“补丁”方法将 MinGW32 特定更改合并到 ATLAS 发行版中,而是将必要的更改合并到最新的 ATLAS 开发版本中。当然,“修补”可能是修复不受支持的 ATLAS 版本的唯一替代方法。
在过去的几天里,我能够使用 MinGW、Msys 和从以下位置下载的 GCC 4.6.2 编译器套件构建经过调整的 ATLAS 3.8.4 静态库:
http://sourceforge.net/projects/mingw/files/
并使用 mingw-get-inst-20111118.exe 安装在具有双 Intel Xeon(具有 MMX、SSE 和 SSE2 的 Pentium 4 [L1 缓存 8 KB,L2 缓存 256 KB],但没有超线程)的 11 岁戴尔工作站 530 上GHz 处理器、400 MHz FSB 和 1024 MB RDRAM,运行 Windows 2000 Professional SP4。
上述修改并不全面,但应该能让您走得更远。我计划记录我对 ATLAS 3.8.4 发行版所做的所有更改,并在验证我的调整配置后将其发布在http://sourceforge.net/projects/math-atlas/forums/上的“Windows 上的 ATLAS”论坛上并使用 LAPACK-3.4.0 构建完整的共享库。
我希望这些信息对您和其他尝试在 Windows 平台上使用 MinGW且不使用Cygwin 构建 ATLAS 的人有所帮助。
特别说明:
使用将输出定向到从调用 tmpnam() 获得的临时文件名的命令调用 system() 将导致在当前驱动器的根目录中创建临时文件。临时文件名以'\\'为前缀,在 MinGW/include/stdio.h 中定义(参见 P_tmpdir)。
重要附录:
(A) 确保在使用 ATLAS/configure 的“-s”和“-b”命令选项指定源目录和构建目录时使用完整路径名。就我而言,以下 sh 脚本显示了我如何从 ATLAS_build 调用 ATLAS/configure:
#!/bin/sh
SRCDIR=/g/Progs/MinGW/msys/1.0/home/GaryD/temp/ATLAS
BLDDIR=/g/Progs/MinGW/msys/1.0/home/GaryD/temp/ATLAS_build
LAPACK=/g/Progs/MinGW/lib/gcc/mingw32/4.6.2/liblapack.dll.a
CC=gcc
C_DEFS="-D c -DL2SIZE=262144" # Not used, set using -f 256
F_DEFS="-D f ''" # Not used, let configure set these
C_FLGS="--cc=$CC --with-netlib-lapack=$LAPACK"
D_FLGS="-d s $SRCDIR -d b $BLDDIR"
A_FLGS="-O 8 -s 1 -A 20 -V 8 -b 32 -f 256 -t 2 -m 1495"
S_FLGS="-Si bozol1 1 -Si archdef 0 -Si cputhrchk 0"
$SRCDIR/configure $C_FLGS -v 2 $D_FLGS $A_FLGS $S_FLGS
(B) 我相信首选的构建目录被假定为 ATLAS 源目录下的子目录,例如 ATLAS/ATLAS_build,因为 ATLAS/bin/ 不可能找到文件 ../../CONFIG/error.txt atlas_install.c 如果源目录和构建目录在同一级别。
(C) 不要犯我在假设“-m ####”配置选项隐式创建“-D c DPentiumCPS=####”配置标志时所犯的错误。您可能需要显式传递“-D c -DPentiumCPS=####”或“-D c -DWALL”,如“ATLAS 安装指南”第 3.4 节“更改 ATLAS 执行计时方式”中所述在这里查看:
http://math-atlas.sourceforge.net/atlas_install/atlas_install.html#SECTION00044000000000000000
通过不使用周期精确的壁计时器,健全性测试的结果,例如来自“xsslvtst.exe -n 167 -r 83 -O 2 cr -U 2 u l”的结果,类似于:
ORD UPLO N NRHS lda ldb TIME MFLOP RESID
=== ==== ====== ====== ====== ====== ========= ======== ===========
C U 167 83 167 167 0.015 257.82 1.762022e-003
C L 167 83 167 167 0.016 241.70 1.870298e-003
R U 167 83 167 167 0.000 2229332063710638100.00 1.870298e-003
R L 167 83 167 167 0.000 2229332063710638100.00 1.762022e-003
4 TESTS RUN, ALL PASSED.
每次调用测试都会为 MFLOP 产生不同的虚假值,这可能是由一个非常、非常、非常小的非零值进行算术除法造成的。在使用“-D c -DWALL”重建 ATLAS 后,这些 MFLOP 结果(无疑还有其他计时措施)得到了纠正。
(D) ATLAS/CONFIG/src/probe_OS.c 的第 35 行需要检查 MinGW,如下所示:
else if(strstr(ln, "WIN") || strstr(ln, "MINGW"))
并在 ATLAS/CONFIG/src/Makefile 中的 "IRunArchInfo_linux: xarchinfo_linux" 块之后插入以下内容(只需剪切、粘贴和编辑 Makefile 中的 IRunArchInfo_linux 块):
IRunArchInfo_winnt: xarchinfo_x86
- rm -f config0.out
$(MAKE) $(atlrun) atldir=$(mydir) exe=xarchinfo_x86 args="$(args)" \
redir=config0.out
- cat config0.out
(E) 可能需要将 ATLAS/CONFIG/src/atlconf.txt 文件中的 gcc-4 行更改为 gcc,因为 MinGW gcc 可执行文件只是 gcc.exe 而不是 gcc-4.exe MinGW32 gcc 编译器套件。ATLAS 开发人员可能更倾向于使用配置标志来覆盖编译器选择和更改/附加编译标志,而不是编辑 atlconf.txt 文件(请参阅“ATLAS 安装指南”的第 3.2 节);但我很不耐烦。
(F) 如果您为我的架构指定带有“-V 8”ATLAS/configure 选项的 SSE2,则必须对 ATLAS/include/atlas_asm.h 文件进行以下更改。
第 133 行来自:
#if defined(ATL_SSE1) && !defined(ATL_3DNow)
至:
#if (defined(ATL_SSE1) || defined(ATL_SSE2)) && !defined(ATL_3DNow)
atlas-win32 mingw32 msys