能否在CMake与Jam间互相调用Jamfile和Jamrule?遗留代码迁移咨询
混合Jam与CMake构建的可行方案(分而治之迁移策略)
我刚好有过类似的混合构建迁移经验,来给你梳理下针对需求的具体方案:
在CMake中调用Jamfile/Jamrule
你提到的自定义目标调用Jam程序是基础方案,这里补充如何复用已有Jamrule的技巧:
基础自定义目标调用Jamfile
这是最直接的方式,用CMake的add_custom_target或add_custom_command触发完整的Jam构建:# 构建整个Jam项目 add_custom_target(legacy_jam_all COMMAND jam -f ${CMAKE_SOURCE_DIR}/legacy/Jamfile WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/legacy COMMENT "Building legacy code with Jam" ) # 或者针对单个产物,用add_custom_command生成依赖 add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/legacy/libfoo.a COMMAND jam -f ${CMAKE_SOURCE_DIR}/legacy/Jamfile libfoo WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/legacy DEPENDS ${CMAKE_SOURCE_DIR}/legacy/foo.cpp COMMENT "Building libfoo with Jam" )复用已有Jamrule的技巧
直接在CMake里调用单个Jamrule没有原生支持,但可以通过轻量包装Jam脚本实现:- 写一个小型的Jam脚本(比如
call_jamrule.jam),引入原Jamfile并调用目标规则:# 引入原Jamfile,加载其中定义的Jamrule include "../legacy/Jamfile"; # 调用你需要的Jamrule,比如编译某个目标 MyCustomJamrule my_target : src1.cpp src2.h ; - 在CMake中调用这个脚本,生成指定产物:
add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/legacy/my_target.o COMMAND jam -f ${CMAKE_SOURCE_DIR}/scripts/call_jamrule.jam WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/legacy DEPENDS ${CMAKE_SOURCE_DIR}/legacy/src1.cpp ${CMAKE_SOURCE_DIR}/legacy/src2.h COMMENT "Using Jamrule to build my_target.o" )
这种方式能最大化复用已有Jam规则,不用重新在CMake中实现逻辑。
- 写一个小型的Jam脚本(比如
处理依赖传递
记得把Jam生成的产物作为CMake目标的依赖,比如:add_executable(my_cmake_app main.cpp) # 确保Jam产物先构建完成 add_dependencies(my_cmake_app legacy_jam_all) target_link_libraries(my_cmake_app ${CMAKE_BINARY_DIR}/legacy/libfoo.a)
在Jam中调用CMake
如果需要反向调用(比如部分模块已迁移到CMake),可以通过自定义Jamrule实现:
- 编写调用CMake的Jamrule
在你的Jamfile中添加自定义规则,触发CMake构建:
这样就能在Jam构建流程中触发CMake的目标构建,并使用其产物。rule BuildCMakeTarget { actions { # 调用CMake构建指定目标,假设CMake构建目录在cmake_build下 cmake --build $(CMAKE_BUILD_DIR) --target $(1) } } # 使用这个规则,比如构建cmake模块中的libbar BuildCMakeTarget libbar; # 依赖CMake生成的产物 MyJamrule my_legacy_app : src.cpp $(CMAKE_BUILD_DIR)/libbar.a ;
分而治之的迁移建议
- 优先迁移独立、无复杂Jamrule依赖的模块到CMake,剩下的模块通过CMake调用Jam构建,逐步减少Jam的范围。
- 对于共用的构建逻辑(比如编译选项、链接规则),可以先抽象成CMake函数/宏,慢慢替代对应的Jamrule,降低迁移成本。
- 每次迁移后验证产物一致性,确保混合构建的输出和原纯Jam构建一致,避免引入隐性问题。
内容的提问来源于stack exchange,提问作者Guruprasad Bhat
相关产品推荐
相关产品推荐

