我有一个项目,其中一些f90文件需要使用常规gfortran编译器进行编译,有些需要使用mpifort包装器进行编译。我不知道如何正确编写CMake文件以适应这一点。另外,我之前从未使用过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.f90
和mpi_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 :(得分: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}")
这将以mpifort编译它们的方式编译所有streetcanyon源代码,在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})