2017-05-31 303 views
0

我有一个项目,需要使用常规gfortran编译器编译一些f90文件,有些需要使用mpifort包装器进行编译。我不知道如何正确编写CMake文件来适应这种情况。另外,我从来没有使用过CMake,也不熟悉它,但我试图从文档和(大部分是过时的)教程中了解。用gfortran和mpifort编写用于Fortran项目的CMake文件

我的项目目录如下所示:

├── CMakeLists.txt 
├── README.md 
├── bin 
├── build 
├── compile 
├── src 
│   ├── CMakeCache.txt 
│   ├── CMakeFiles 
│   │   ├── 3.8.1 
│   │   │   ├── CMakeCCompiler.cmake 
│   │   │   ├── CMakeCXXCompiler.cmake 
│   │   │   ├── CMakeDetermineCompilerABI_C.bin 
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin 
│   │   │   ├── CMakeDetermineCompilerABI_Fortran.bin 
│   │   │   ├── CMakeFortranCompiler.cmake 
│   │   │   ├── CMakeSystem.cmake 
│   │   │   ├── CompilerIdC 
│   │   │   │   ├── CMakeCCompilerId.c 
│   │   │   │   ├── a.out 
│   │   │   │   └── tmp 
│   │   │   ├── CompilerIdCXX 
│   │   │   │   ├── CMakeCXXCompilerId.cpp 
│   │   │   │   ├── a.out 
│   │   │   │   └── tmp 
│   │   │   └── CompilerIdFortran 
│   │   │    ├── CMakeFortranCompilerId.F 
│   │   │    ├── a.out 
│   │   │    └── tmp 
│   │   ├── CMakeDirectoryInformation.cmake 
│   │   ├── CMakeOutput.log 
│   │   ├── CMakeTmp 
│   │   ├── Makefile.cmake 
│   │   ├── Makefile2 
│   │   ├── TargetDirectories.txt 
│   │   ├── cmake.check_cache 
│   │   ├── feature_tests.bin 
│   │   ├── feature_tests.c 
│   │   ├── feature_tests.cxx 
│   │   ├── progress.marks 
│   │   └── streetcanyon.dir 
│   │    ├── DependInfo.cmake 
│   │    ├── INC_BBB.f90.o 
│   │    ├── INC_BBB.f90.o.provides.build 
│   │    ├── INC_BC.f90.o 
│   │    ├── INC_BC.f90.o.provides.build 
│   │    ├── INC_BOUNDC.f90.o 
│   │    ├── INC_BOUNDC.f90.o.provides.build 
│   │    ├── INC_BUOY.f90.o 
│   │    ├── INC_BUOY.f90.o.provides.build 
│   │    ├── INC_COEF.f90.o 
│   │    ├── INC_COEF.f90.o.provides.build 
│   │    ├── INC_COEFB.f90.o 
│   │    ├── INC_COEFB.f90.o.provides.build 
│   │    ├── INC_GEO.f90.o 
│   │    ├── INC_GEO.f90.o.provides.build 
│   │    ├── INC_INDEX.f90.o 
│   │    ├── INC_INDEX.f90.o.provides.build 
│   │    ├── INC_OBSTACLE.f90.o 
│   │    ├── INC_OBSTACLE.f90.o.provides.build 
│   │    ├── INC_PAR.f90.o 
│   │    ├── INC_PAR.f90.o.provides.build 
│   │    ├── INC_PRINT.f90.o 
│   │    ├── INC_PRINT.f90.o.provides.build 
│   │    ├── INC_SOURCE.f90.o 
│   │    ├── INC_SOURCE.f90.o.provides.build 
│   │    ├── INC_STAT.f90.o 
│   │    ├── INC_STAT.f90.o.provides.build 
│   │    ├── INC_TIME.f90.o 
│   │    ├── INC_TIME.f90.o.provides.build 
│   │    ├── INC_TITLE.f90.o 
│   │    ├── INC_TITLE.f90.o.provides.build 
│   │    ├── INC_TREES.f90.o 
│   │    ├── INC_TREES.f90.o.provides.build 
│   │    ├── INC_UVW.f90.o 
│   │    ├── INC_UVW.f90.o.provides.build 
│   │    ├── INC_VEC.f90.o 
│   │    ├── INC_VEC.f90.o.provides.build 
│   │    ├── INC_WALL.f90.o 
│   │    ├── INC_WALL.f90.o.provides.build 
│   │    ├── build.make 
│   │    ├── cmake_clean.cmake 
│   │    ├── cmake_clean_Fortran.cmake 
│   │    ├── depend.internal 
│   │    ├── depend.make 
│   │    ├── flags.make 
│   │    ├── fortran.internal 
│   │    ├── inc_bbb.mod.stamp 
│   │    ├── inc_bc.mod.stamp 
│   │    ├── inc_boundc.mod.stamp 
│   │    ├── inc_buoy.mod.stamp 
│   │    ├── inc_coef.mod.stamp 
│   │    ├── inc_coefb.mod.stamp 
│   │    ├── inc_geo.mod.stamp 
│   │    ├── inc_index.mod.stamp 
│   │    ├── inc_obstacle.mod.stamp 
│   │    ├── inc_par.mod.stamp 
│   │    ├── inc_print.mod.stamp 
│   │    ├── inc_source.mod.stamp 
│   │    ├── inc_stat.mod.stamp 
│   │    ├── inc_time.mod.stamp 
│   │    ├── inc_title.mod.stamp 
│   │    ├── inc_trees.mod.stamp 
│   │    ├── inc_uvw.mod.stamp 
│   │    ├── inc_vec.mod.stamp 
│   │    ├── inc_wall.mod.stamp 
│   │    ├── link.txt 
│   │    └── progress.make 
│   ├── INC_BBB.f90 
│   ├── INC_BC.f90 
│   ├── INC_BOUNDC.f90 
│   ├── INC_BUOY.f90 
│   ├── INC_COEF.f90 
│   ├── INC_COEFB.f90 
│   ├── INC_GEO.f90 
│   ├── INC_INDEX.f90 
│   ├── INC_OBSTACLE.f90 
│   ├── INC_PAR.f90 
│   ├── INC_PAR.f90_8ob 
│   ├── INC_PRINT.f90 
│   ├── INC_SOURCE.f90 
│   ├── INC_STAT.f90 
│   ├── INC_TIME.f90 
│   ├── INC_TITLE.f90 
│   ├── INC_TREES.f90 
│   ├── INC_UVW.f90 
│   ├── INC_VEC.f90 
│   ├── INC_WALL.f90 
│   ├── Makefile 
│   ├── cmake_install.cmake 
│   ├── grid_binary 
│   ├── grid_binary(8\ obsttacles) 
│   ├── inc_bbb.mod 
│   ├── inc_bc.mod 
│   ├── inc_boundc.mod 
│   ├── inc_buoy.mod 
│   ├── inc_coef.mod 
│   ├── inc_coefb.mod 
│   ├── inc_geo.mod 
│   ├── inc_index.mod 
│   ├── inc_obstacle.mod 
│   ├── inc_par.mod 
│   ├── inc_print.mod 
│   ├── inc_source.mod 
│   ├── inc_stat.mod 
│   ├── inc_time.mod 
│   ├── inc_title.mod 
│   ├── inc_trees.mod 
│   ├── inc_uvw.mod 
│   ├── inc_vec.mod 
│   ├── inc_wall.mod 
│   ├── mpi_par.f90 
│   ├── source 
│   ├── streetcanyon.f90 
│   └── streetcanyon.f90~ 

./src/目录streetcanyon.f90mpi_par.f90需要使用mpifort进行编译,其余的可以通过gfortran来完成。需要将streetcanyon.f90编译为最终的可执行文件。我一直在使用它包含在项目的根目录下面CMakeList.txt尝试:

#./CMakeList.txt 
cmake_minimum_required (VERSION 3.8.0) 
project(mpi) 
enable_language (Fortran) 

file(GLOB SOURCES src/*.f90) 

add_executable(streetcanyon ${SOURCES}) 

我也是,如果我下面Fortran的合适的项目结构不知道。

+0

为什么不能用MPI包装器编译所有东西?这就是我在我的项目中所做的。 –

+0

这可能是可能的,但我认为这可能是不好的做法。例如,当调用“mpifort”而不是'gfortran'时,我不确切地知道'底层'是怎么回事。 – Lars

+0

真的没什么不好。我看不出为什么不用MPI包装器编译所有的东西。你甚至可以决定哪些是,哪些不是......? –

回答

0

只需使用CMake的FindMPI模块。它将从mpifort中提取编译标志和库,并将它们作为常规CMake变量提供。你所要做的就是将这些标志应用到你的库中。唯一困难的部分是有几个不同的事情必须得到应用。下面是你如何使用它的一个例子:

cmake_minimum_required (VERSION 3.8.0) 
project(mpi) 
enable_language (Fortran) 

find_package(MPI) 
if(NOT MPI_Fortran_FOUND) 
    message(FATAL_ERROR "Could not find Fortran MPI. Please set MPI_Fortran_COMPILER to point to the mpifort wrapper.") 
endif() 

include_directories(${MPI_Fortran_INCLUDE_PATH}) 
add_compile_options(${MPI_Fortran_COMPILE_FLAGS}) 

file(GLOB SOURCES src/*.f90) 

add_executable(streetcanyon ${SOURCES}) 
target_link_libraries(streetcanyon ${MPI_Fortran_LIBRARIES}) 
set_property(TARGET streetcanyon APPEND_STRING PROPERTY LINK_FLAGS "${MPI_Fortran_LINK_FLAGS}") 

这将编译所有的streetcanyon来源的方式,mpifort会编译他们,这应该是在用例的99%以下的罚款。如果你真的想只编译一些文件,如mpifort会的,就像你说的话,而不是

add_compile_options(${MPI_Fortran_COMPILE_FLAGS}) 

可以通过MPI编译选项,只有特定的源文件,带有几分小提琴演奏的:

set(MPI_SOURCES foo.f90 bar.f90...) 
set(NO_MPI_SOURCES baz.f90...) 

# convert CMake list to string for PROPERTY COMPILE_FLAGS 
set(MPI_Fortran_COMPILE_FLAGS_STR "") 
foreach(ELEMENT ${MPI_Fortran_COMPILE_FLAGS}) 
    set(MPI_Fortran_COMPILE_FLAGS_STR "${MPI_Fortran_COMPILE_FLAGS_STR } ${ELEMENT}") 
endforeach() 

set_property(SOURCE ${MPI_SOURCES} PROPERTY COMPILE_FLAGS ${MPI_Fortran_COMPILE_FLAGS_STR}) 

...later... 
add_executable(streetcanyon ${MPI_SOURCES} ${NO_MPI_SOURCES}) 
+0

谢谢!你的解释非常彻底,我会尽快尝试。希望我能够以积极的消息回复你 – Lars

相关问题