使用模块为 Fortran-90+ 进行 CMake 并行构建

标签 cmake makefile fortran parallel-builds

当我使用由所有可执行文件共享的 Fortran 模块并使用 make -j 并行构建时,我在使用 CMake 构建多个 Fortran-90+ 可执行目标时遇到问题。问题似乎是编译后的目标文件放置在每个目标的不同子目录中,CMakeFiles/targetName.dir/src/file.f90.o,而模块文件放置在同一目录中对于每个目标(我可以通过设置 Fortran_MODULE_DIRECTORY 来更改此目录,但它仍然是所有模块文件的相同目录)。问题是所有目标开始并行编写这些模块文件,我得到一个 fatal error :无法将模块文件“module.mod0”重命名为“module.mod”:没有这样的文件或目录 使用 gfortran 时(显然会创建一个 .mod0 文件,然后将其重命名为 .mod)。当我在没有 -j 选项(串行构建)的情况下发出 make 时,问题不会出现。

我可以看到两个解决方案,但我不知道如何实现它们。首先,将所有目标的目标文件放在同一目录中,而不是特定于目标的目录中。这可能是首选选项,因为我不必为 N 个目标编译 N 次共享源文件。然后 make 进程将识别目标文件存在,并且不会再次编译相应的源文件,因此不会再次触及 .mod(0) 文件(我可能需要使所有以下目标都依赖于第一个)。

第二种解决方案是将 .mod(0) 文件放在特定于目标的目录中,这样它们就不会被其他目标覆盖或删除。这将解决我的问题,即使它仍然涉及比必要更多的编译。我不知道如何完成任一选项,因此欢迎提供任何提示或替代解决方案。

最佳答案

@RaulLaasner 在对问题的评论中提供了我正在寻找的答案:

I would create an additional target in the form of a core library of the relevant source files, which can then be linked to all executables. This should work in parallel. The mod files can still be in put into a single directory.

我使用 add_library()target_link_libraries() 来实现这一点。

请注意,例如Gentoo ebuild 脚本将 --as-needed 添加到链接器,这可能会导致 undefined references当您链接它和外部库以形成可执行文件时,在您的核心库中。为防止这种情况,请确保首先将外部库链接到核心库。为此,我的 CMakeListst.txt 包含:

add_library( "Core" STATIC src/functions.f90 src/routines.f90 )  # creates libCore.a
target_link_libraries( Core ${EXTERNAL_LIBRARIES} )              # link external libraries to libCore.a
...
add_executable( myProgram1 src/myProgram1.f90 )                  # creates the first executable
target_link_libraries( myProgram1 Core )                         # links libCore.a to myProgram1 

可以重复最后两行来构建其他可执行文件(例如使用 foreach())。

关于使用模块为 Fortran-90+ 进行 CMake 并行构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29728867/

相关文章:

file-io - 并行读取多个文件并将它们存储在共享变量中

cmake - 使用CMake编译Vala项目

我可以跳过 cmake 编译器测试或避免 "error: unrecognized option ' -rdynamic'"

multidimensional-array - 矩阵的 Fortran 转置不适用于非二维数组

fortran - 我可以有一个指向可分配数组组件中项目的指针吗?

linux - Bash:无法在 Linux 上启动使用 make 创建的程序

c++ - 尝试将 Boost 与 CMake 链接时遇到 LNK2019 错误

cmake - 如何在cmake中进行代码覆盖

makefile - 找不到 cl.h - 如何在生成文件中链接

latex - Autoconf/Automake 条件和 dist 规则