2017-05-31 33 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