我有一个C++代码,可以使用MPI支持编译,具体取决于某个预处理器标志; 缺少相应的标志,源编译为非并行版本.
我想设置的Makefile.am,以便它编译双方的MPI并行和串行版本,如果选项
./configure
中给出.
这是一个问题:MPI有自己的C++编译器包装器,并坚持使用它而不是标准C++编译器编译和链接源代码.如果我自己编写Makefile,我必须做这样的事情:
myprog.seq: myprog.cxx $(CXX) ... myprog.cxx myprog.mpi: myprog.cxx $(MPICXX) -DWITH_MPI ... myprog.cxx
有没有办法告诉automake在编译MPI启用的程序版本时必须使用$(MPICXX)而不是$(CXX)?
我有同样的问题,我发现没有真正好的方法让autotools 有条件地使用MPI编译器来处理特定目标.自动工具是善于指出使用基于什么语言源写入(其中编译器CC
,CXX
,FC
,F77
,等),但它确实是在搞清楚是否要使用MPI编译器为特定的目标并不好.您可以设置MPICC,MPICXX等,但如果您以这种方式使用编译器,则基本上必须重写目标的所有Makefile规则(如上所述).如果你这样做,那么写一个automake文件有什么意义呢?
其他人建议像外部库一样使用MPI,这是我提倡的方法,但你不应该手工完成,因为不同的MPI安装有不同的标志集,它们传递给编译器,它们可以依赖于你正在编译的语言.
好消息是,我所知道的所有当前正在运行的MPI编译器都支持内省参数,例如-show
,-show-compile
或-show-link
.您可以从脚本中自动提取参数.
因此,我要做的就是创建一个m4
脚本,从MPI编译器中提取定义,包含,库路径,库和链接器标志,然后将它们分配给您可以在您的文件中使用的变量Makefile.am
.这是脚本:
lx_find_mpi.m4
这使得MPI的工作方式与automake期望的方式相同.顺便说一句,这是CMake在他们的FindMPI
模块中使用的方法,我发现它在那里工作得很好.它使构建更加方便,因为你可以为你的目标做这样的事情:
bin_PROGRAMS = mpi_exe seq_exe # This is all you need for a sequential program seq_exe_SOURCES = seq_exe.C # For an MPI program you need special LDFLAGS and INCLUDES mpi_exe_SOURCES = mpi_exe.C mpi_exe_LDFLAGS = $(MPI_CXXLDFLAGS) INCLUDES = $(MPI_CXXFLAGS)
其他语言也有类似的标志,因为像我说的那样,特定的标志和库可能会有所不同,具体取决于您使用的语言的MPI编译器.
lx_find_mpi.m4
还设置了一些shell变量,以便您可以在configure.ac
文件中测试是否找到了MPI.例如,如果您正在寻找MPI C++支持,您可以测试$have_CXX_mpi
宏是否找到它.
我用mvapich和OpenMPI测试了这个宏,以及BlueGene机器上的自定义MPICH2实现(尽管它没有解决你在那里看到的所有交叉编译问题).如果有什么不起作用,请告诉我.我想让宏保持尽可能健壮.
对不起,使用自动驾驶仪使用MPI非常困难.我一直在努力寻找一个好的解决方案.我有一个源树,其中有一个库,然后是使用该库的子文件夹中的许多程序.一些文件夹是mpi程序,但是当我尝试使用in用MPI编译器替换CXX时Makefile.am
.
if USE_MPI MPIDIR = $(MPICOMPILE) MPILIB = $(MPILINK) CXX=@MPICXX@ F77=@MPIF77@ MPILIBS=$(MPILINK) endif
我明白了
CXX was already defined in condition TRUE, which includes condition USE_MPI ... configure.ac:12: ... `CXX' previously defined here
我没有指定编译器的规则,所以也许有办法做到这一点.
SUBDIRS = . bin_PROGRAMS = check.cmr check_ccmr_SOURCES = check_gen.cpp check_ccmr_CXXFLAGS = -I$(INCLUDEDIR) $(MPIDIR) check_ccmr_LDADD = -L$(LIBDIR) check_ccmr_LDFLAGS = $(MPILIB)