如何用add_custom_command构建Fortran库并获取.so与.mod文件
解决CMake调用外部Makefile获取Fortran .mod文件的问题
问题核心在于你的自定义目标仅依赖共享库文件,CMake会认为只要.so生成完成,目标就已就绪,不会等待.mod文件的生成与移动。即便add_custom_command中列出了.mod作为输出,若自定义目标不依赖它,CMake也不会主动追踪该文件的状态。
修复步骤:
- 明确所有需要的输出文件:将
.so和所有必需的.mod文件都列入add_custom_command的OUTPUT列表,若存在多个.mod文件,不要遗漏。 - 让自定义目标依赖所有输出文件:修改
add_custom_target的DEPENDS项,包含所有输出文件,确保CMake等待所有文件生成完成后才标记目标就绪。
修改后的CMake代码:
# 定义所有需要从外部Makefile获取的输出文件 set(FORTLIB_OUTPUTS ${LIBDIR}/lib/myfortlib.so ${LIBDIR}/lib/myfortlib.mod # 若有其他.mod文件(如utils.mod、types.mod),在此补充 ) # 调用外部Makefile生成所有指定文件 add_custom_command( OUTPUT ${FORTLIB_OUTPUTS} COMMAND make WORKING_DIRECTORY ${LIBDIR} # 可选:添加对Makefile本身的依赖,确保修改Makefile时自动重新构建 DEPENDS ${LIBDIR}/Makefile ) # 自定义目标依赖所有输出文件,确保所有文件都生成完成 add_custom_target(myfortlib DEPENDS ${FORTLIB_OUTPUTS})
额外优化提示:
- 如果
.mod文件数量较多,不想逐个手动列出,可以在外部Makefile中新增一个目标,完成所有.mod文件复制后生成一个标记文件(如mods_ready),再让add_custom_command输出该标记文件,自定义目标依赖此标记文件。示例Makefile片段:
对应CMake代码调整为:all: libmyfortlib.so mods_ready mods_ready: cp *.mod lib/ touch mods_readyadd_custom_command( OUTPUT ${LIBDIR}/lib/myfortlib.so ${LIBDIR}/mods_ready COMMAND make WORKING_DIRECTORY ${LIBDIR} ) add_custom_target(myfortlib DEPENDS ${LIBDIR}/lib/myfortlib.so ${LIBDIR}/mods_ready) - 务必确认外部Makefile的
all目标包含了.mod文件的生成与复制逻辑,否则即便CMake配置了依赖,make命令也不会生成这些文件。
内容的提问来源于stack exchange,提问作者Dorito Johnson
相关产品推荐
相关产品推荐

