使用CMake构建多子文件夹Fortran模块项目时出现.mod文件缺失及链接错误
代码问题逐项排查
对照你贴的CMake配置,存在几处直接导致编译报错的逻辑错误:
- 依赖关系写反:
target_link_libraries(utilities)这行的实际作用是给utilities目标自身添加空链接,完全没有建立ui库对utilities的编译依赖,CMake调度编译任务时不会优先编译utilities,自然不会等mod文件生成就启动后续目标的编译。 - 模块查找路径缺失:没有统一设置Fortran模块的输出目录,所有.mod文件会默认散落在各个目标的独立构建路径下,仅手动include utilities的源码和二进制目录,根本覆盖不到其他库生成的mod文件。
- 变量复用错误:
add_executable(rse ${srcFiles})里的srcFiles变量,在前面定义driver库时被赋值为driver目录下的f90文件,根本没有把可执行程序的入口源码纳入编译,最终链接时自然找不到对应符号。 - 冗余配置:手动给每个目标设置
LINKER_LANGUAGE Fortran属于多余操作,只要源文件是.f90后缀,CMake会自动识别Fortran语言。
修正后的配置方案
Fortran项目用CMake构建时,只要遵循两个核心规则就能解决mod文件生成顺序、找不到的问题:
- 统一所有Fortran模块的输出路径,避免文件分散
- 通过
target_link_libraries显式建立目标间的依赖关系,CMake会自动基于依赖拓扑保证编译顺序——必须等被依赖目标生成完全部.mod文件,才会启动依赖方的编译,同时自动传递模块查找路径。
修正后的完整配置参考:
# 最顶层CMake配置,设置所有Fortran模块统一输出到构建目录下的mod文件夹 set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/mod) # 配置utilities静态库 file(GLOB utilities_src CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/utilities/*.f90 ) add_library(utilities STATIC ${utilities_src}) # 声明模块查找路径为PUBLIC,所有链接utilities的目标会自动继承这个查找路径 target_include_directories(utilities PUBLIC ${CMAKE_Fortran_MODULE_DIRECTORY}) # 配置ui静态库 file(GLOB ui_src CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/ui/*.f90 ) add_library(ui STATIC ${ui_src}) # 修正依赖:ui直接依赖utilities,而不是给utilities加空链接 target_link_libraries(ui PUBLIC utilities) # 配置driver静态库 file(GLOB driver_src CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/driver/*.f90 ) add_library(driver STATIC ${driver_src}) # 声明driver对ui、utilities的依赖,CMake会自动安排编译顺序 target_link_libraries(driver PUBLIC ui utilities) # 配置可执行文件,单独定义对应源码变量,避免复用之前的srcFiles file(GLOB rse_src CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/app/main.f90 # 替换为你实际存放程序入口的源码路径 ) add_executable(rse ${rse_src}) target_link_libraries(rse PRIVATE driver utilities) install(TARGETS rse RUNTIME DESTINATION bin)
对应报错的原因匹配
- 出现
Can't open module file ‘utilities.mod’ for reading at (1): No such file or directory:本质是没有建立正确的依赖编译顺序,并行编译时driver的源码先于utilities.mod生成启动编译,编译器自然找不到还没生成的文件。 - 出现
undefined reference to__command_line_MOD_read_command_line'`:一方面是依赖传递失效,链接时没有把utilities库的符号链到最终可执行文件;另一方面是入口源码没有被正确纳入编译范围,符号自然无法解析。
内容的提问来源于stack exchange,提问作者if_summer
相关产品推荐
相关产品推荐

