我度过了一个痛苦的下午,试图将Fortran-90模块添加到使用CMake构建的大型多语言库集(主要是C ++)中,而此时我显然正在盘旋。在线信息的匮乏可能对我有帮助,而CMake文档一如既往地难以理解。
库集太大而无法正常使用(因此我一直无法获得好的小型复制器),但这是本质。每个库都位于其自己的目录下,并在其下面有一个测试目录。我已经将包含模块的F90文件添加到目录之一,我将其称为low_library
。该目录的内容类似于:
low_library:
CMakeList.txt
file1.cc
file1.hh
file2.cc
file2.hh
my_module.f90
test:
CMakeList.txt
test1.cc
test2.cc
test3.cc
my_module_test.f90
,除了更多的.cc和.hh文件。在库目录的CMakeList.txt
文件中,我包含的指令
add_library(low_library STATIC "")
target_sources(low_library
PUBLIC:
file1.hh
file2.hh
PRIVATE:
file1.cc
file2.cc
)
还有更多,但显然不相关。
因此,第一个问题是将my_module.f90
放在哪里。我希望将my_module.f90.o
包含在liblow_library.a
文件中,但是我需要my_module.mod
文件对我正在构建的其他库(以及库集的用户)可见。所以我添加了行
set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/fortran_modules)
在我的CMakeList.txt文件的顶部,将my_module.f90
添加到target_sources()
PUBLIC列表的PRIVATE部分,然后... sigh ...构建系统会将.mod文件放在构建目录中,而不放在${CMAKE_INSTALL_PREFIX}/fortran_modules
中。其他库看不到它并无法构建。
因此,现在我将my_module.f90
放在target_sources()
的PUBLIC部分中,然后重试。这次模块文件到达了我期望的位置,我的测试目录可以看到它并成功构建,并且我很高兴,直到继续构建依赖于{{1}的目录high_library
中的下一个库为止。 }。构建过程中出现了真正奇怪的错误:
low_library
再看一下跟踪的其余部分,看来f951: Fatal Error: Can't rename module file â/scratch/kgbudge/develop/install/fortran_modules/cta_mesh_generator.mod0â to â/scratch/kgbudge/develop/install/fortran_modules/cta_mesh_generator.modâ: No such file or directory
的公共接口中有my_module.g90
,low_library
的构建会忽略我的high_library
中已经存在的内容,并且在${CMAKE_INSTALL_PREFIX}/fortran_modules
中构建其d-mned .mod文件的副本。由于我们拥有高性能的构建服务器并且始终并行构建(${CMAKE_INSTALL_PREFIX}/fortran_modules
是典型的),因此这意味着竞争的构建作业之间存在竞争状态。
好的,我知道。我需要包括这行
make -j16
target_include_directories(low_library PUBLIC ${CMAKE_INSTALL_PREFIX}/fortran_modules)
的{{1}}文件的开始附近,因此它知道在哪里可以找到模块,并且不会尝试构建自己的模块。除了这个没有帮助。
我在网上找不到任何可以给我任何线索的线索,说明正在发生的事情或如何解决它。
答案 0 :(得分:0)
问题似乎是我有我的
set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/fortran_modules)
仅在产生或使用新模块的库中。但是其他库使用了包含该模块的库,即使它们实际上并未使用该模块,也需要查看该模块的副本。我认为。
无论如何,将此行移至CMakeLists.txt根目录使我能够成功构建整个库。我似乎仍然有些警告:
f951: Warning: Nonexistent include directory â/srcâ [-Wmissing-include-dirs]
但至少所有这些都可以构建。