因项目需要在 Windows 下测试开发的程序, 所以研究了一下如何在 Windows 下搭建基于 gcc 的开源开发环境。

MSYS2 是 Windows 下的一款开源软件构建和发布平台, 网址为 。 它提供了和 Linux 系统几乎一样开发接口和环境, 而且它自带了一个软件包的管理工具 pacman, 可以像 Ubutnu 中 apt 一样管理需要的开源软件包。

MSYS2 可以在其官网下载, 有 32 位和 64位版本的。 因为现在大部分机器和系统都是 64 位的, 所以下面只介绍 64 位版本安装情况。

下载 msys2-x86_64-latest.exe 运行安装, 默认安装在 C:\msys64。

安装之后在目录 C:\msys64 下, 点击运行 mingw64命令行窗口(注意这里我们不用msys2命令行, 因为我们下面只用到 64 位的程序)。 用下面命令更新 pacman 的服务器列表文件, 这样后面更新系统和安装软件包会快一点:

$ echo "Server = Server = http://mirror.bit.edu.cn/msys2/REPOS/MINGW/i686/ Server = http://jaist.dl.sourceforge.net/project/msys2/REPOS/MINGW/i686/ Server = http://www.mirrorservice.org/sites/download.sourceforge.net/pub/sourceforge/m/ms/msys2/REPOS/MINGW/i686/ Server = ftp://148.251.42.38/MINGW/i686/ Server = http://downloads.sourceforge.net/project/msys2/REPOS/MINGW/i686/ " >> /etc/pacman.d/mirrorlist.mingw32 # 附加到文件尾部 $ echo " Server = http://mirrors.ustc.edu.cn/msys2/REPOS/MINGW/x86_64/ Server = http://mirror.bit.edu.cn/msys2/REPOS/MINGW/x86_64/ Server = http://jaist.dl.sourceforge.net/project/msys2/REPOS/MINGW/x86_64/ Server = http://www.mirrorservice.org/sites/download.sourceforge.net/pub/sourceforge/m/ms/msys2/REPOS/MINGW/x86_64/ Server = ftp://148.251.42.38/MINGW/x86_64/ Server = http://downloads.sourceforge.net/project/msys2/REPOS/MINGW/x86_64/ " >> /etc/pacman.d/mirrorlist.mingw64 $ echo "Server = http://mirror.bit.edu.cn/msys2/REPOS/MSYS2/$arch/ Server = http://mirrors.ustc.edu.cn/msys2/msys/$arch/ Server = http://jaist.dl.sourceforge.net/project/msys2/REPOS/MSYS2/$arch Server = http://www.mirrorservice.org/sites/download.sourceforge.net/pub/sourceforge/m/ms/msys2/REPOS/MSYS2/$arch Server = ftp://148.251.42.38/MSYS2/$arch Server = http://downloads.sourceforge.net/project/msys2/REPOS/MSYS2/$arch " >> /etc/pacman.d/mirrorlist.msys接着用下面的命令把系统更新到最新。

$ pacman -Suu第一次更新完, 可能需要关闭命令行。

下面在 mingw64 命令行中安装需要的编译器和开发工具, 注意这里只安装 64 位的版本:

$ pacman -S base-devel # 基础工具 $ pacman -S mingw-w64-x86_64-toolchain # 编译器gcc, g++, gfortran $ pacman -S git  # git 版本控制软件 $ pacman -S mercurial  # 另一个版本控制 $ pacman -S make  # make 程序 $ pacman -S mingw-w64-x86_64-cmake # CMake安装完成之后, 基本的开发环境就搭建好了。

MSYS2 还有很多已经编译好的开源软件包, 可以通过 pacman 从网上的仓库中搜索、下载和安装。 比如要安装 boost

$ pacman -Ss boost # 搜索 boost mingw32/mingw-w64-i686-boost 1.60.0-2    Free peer-reviewed portable C++ source libraries (mingw-w64) mingw64/mingw-w64-x86_64-boost 1.60.0-2    Free peer-reviewed portable C++ source libraries (mingw-w64) $ pacman -S mingw-w64-x86_64-boost # 安装 64位 boostWindows 下 Mumps 的安装有了上面的环境, 下面将介绍如何利用 mingw64 来编译安装并行直接解法器 MUMPS。

首先, 安装依赖软件包 metis 和 openblas

$ pacman -S mingw-w64-x86_64-metis $ pacman -S mingw-w64-x86_64-openblas下面安装 MUMPS, 但它的安装包需要到官网()填个表, 开发人员会把包发到你的邮箱。

$ tar -xvf MUMPS_5.1.2.tar.gz $ cd MUMPS_5.1.2/ $ cp Make.inc/Makefile.inc.generic.SEQ  ./Makefile.inc下面要对 Makefile.inc 针对 Windows 系统做一些修改, 主要就是告诉 make 命令, MUMPS 依赖包的头文件和库文件在 Windows 系统的什么地方, 具体内容如下:

# Makefile.inc LPORDDIR = $(topdir)/PORD/lib/ IPORD    = -I$(topdir)/PORD/include/ LPORD    = -L$(LPORDDIR) -lpord LMETISDIR = /C/msys64/mingw64/lib IMETIS    = -I/C/msys64/mingw64/include LMETIS    = -L$(LMETISDIR) -lmetis ORDERINGSF  = -Dmetis -Dpord ORDERINGSC  = $(ORDERINGSF) PLAT    = LIBEXT  = .a OUTC    = -o OUTF    = -o RM      = /bin/rm -f CC      = gcc FC      = gfortran FL      = gfortran AR      = ar vr RANLIB  = ranlib INCSEQ  = -I$(topdir)/libseq LIBSEQ  = $(LAPACK) -L$(topdir)/libseq -lmpiseq LIBBLAS = -lopenblas LIBOTHERS = -lpthread CDEFS = -DAdd_ OPTF    = -O -fPIC OPTC    = -O -fPIC OPTL    = -O -fPIC INCS = $(INCSEQ) LIBS = $(LIBSEQ) LIBSEQNEEDED = libseqneeded另外, 在 MUMPS_5.1.2/example 下的 Makefile 中, 也要做些修改, 即在每个例子编译命令后面加下 $(LMETIS) $(LPORD) 两个选项, 如下面 ssimpletest 例子:

ssimpletest:  $(LIBSMUMPS)  $$@.o    $(FL) -o $@ $(OPTL) ssimpletest.o  $(LIBSMUMPS) $(LORDERINGS) $(LMETIS) $(LPORD) $(LIBS) $(LIBBLAS) $(LIBOTHERS)打开 mingw64 的命令行程序, 进入 MUMPS 的源代码目录, make 即可编译 MUMPS。

首先, 在 Matlab 命令行中设置环境变量,

>> setenv('MW_MINGW64_LOC','C:\msys64\mingw64')或者直接在 Windows 系统中添加系统环境变量 MW_MINGW64_LOC, 其值设为 C:\msys64\mingw64, 如何添加系统环境变量请自行网络搜索网络。

在 Matlab 命令行中运行:

>> mex -setup就可以让 Matlab 的 mex 命令识别到 mingw64, 然后就可以用 mingw64 提供的编译器来编译 mex 程序, 并被 Matlab 的程序调用。

但实际上要编译出在 Matlab 中可以直接调用的 mex 程序, 不用 mex 命令, 甚至不用打开 Matlab, 也是可以的。 因为 mex 生成的可执行文件本质是上动态联接库文件, 而且 Matlab 为 Matlab 与 C\C++ 的混合编程提供了相应的函数库, 如:

直接把 MUMPS_5.1.2/MATLAB/ 中 Makefile 文件直接替换为下面的内容:

# MUMPS_5.1.2/MATLAB 下的 Makefile 文件 MATLABROOT  = /C/MATLAB/R2016b MUMPSROOT   = /C/msys64/home/why/software/MUMPS_5.1.2 MINGWROOT   = /C/msys64/mingw64 MUMPSLIBS   = -L${MUMPSROOT}/lib -ldmumps -lmumps_common -lpord -L${MUMPSROOT}/libseq -lmpiseq LIBS        = -L${MINGWROOT}/usr/lib -lmetis -lopenblas -lgfortran                                  # 注意   MEXLIBS     = -L${MATLABROOT}/extern/lib/win64/microsoft -llibmex -llibeng -llibmat -llibmx -llibut # 这两行中引用软件包名字的区别 CC          = gcc CCFLAGS     = -I${MATLABROOT}/extern/include -I${MUMPSROOT}/include -I${MUMPSROOT}/libseq .PHONY: all all: dmumpsmex.mexw64 dmumpsmex.mexw64: mumpsmex.c    @${CC} ${CCFLAGS} -shared -fPIC -DMUMPS_ARITH=MUMPS_ARITH_d -O2 -o $@ $< ${MUMPSLIBS} ${LIBS} ${MEXLIBS}    @strip $@ clean:    @-rm -f *.o *.mexw64注意, 上面 MEXLIBS 变量中索引 Matlab 的库文件时, 用的是 -llibmex -llibeng -llibmat -llibmx -llibut, 而 MUMPSLIBS 和 LIBS 变量中用的是 Linux 下常用的索引库的方式, 如 -lmetis, 其中没有 lib字符串。 我猜 mingw64 用了两种完全不同的方式来处理 mingw64 中软件包和 Windows 系统中的软件包。

最后在 MUMPS_5.1.2/MATLAB/ 下 make, 即可编译出一个dmumpsmex.mexw64文件。 最后打开 Matlab 的命令行, 进入MUMPS_5.1.2/MATLAB/目录, 运行下面例子测试编译是否成功。

>> simple_example写在最后上面用到的脚本都放在我的 github: -scripts 仓库中, 包括 MUMPS 的源文件, 你可以下载下来, 直接用里面的脚本来安装 msys2 和 MUMPS 。 里面以后也会放更多计算数学常用软件包的安装脚本, 敬请期待。

在使用操作系统和各种软件的过程中,我们会积累很多操作性的经验和知识, 但这些经验和知识如果不及时总结,变成文字性的东西,是很容易忘记的。下次再遇到类似的情况, 又要把解决问题的过程走一遍, 这是很低效的做事方式。

最好的方式是及时做好笔记, 并把这些操作性的经验和知识程序化, 变成可执行的程序。 下次再做类似的事情, 就只需要运行程序就可以了, 这样可以大大节省自己的时间。 写笔记和编写程序, 可能需要花点时间, 但这份时间花的非常值得, 因为这份永远失去的时间是可以被复制无穷多份的。