CMake生成Makefile后修改源文件,再次make不重编译问题求助
问题:CMake ExternalProject_Add 修改源码后执行
make不重新编译 用CMake生成Makefile后,首次执行make可正常完成编译;但修改项目源文件后再次执行make,目标文件不会重新编译。不过如果首次编译报错,修复错误后再执行make,则能继续完成编译。
根CMakeLists.txt核心配置如下:
ExternalProject_Add(NAME1 PREFIX NAME1 SOURCE_DIR CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS ) ExternalProject_Add(NAME2 PREFIX NAME2 SOURCE_DIR CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS CMAKE_ARGS DEPENDS NAME1 )
原因分析
ExternalProject_Add默认采用离线构建模式,它仅在首次构建时处理源码目录,后续不会自动监听原始源码文件的变更。其依赖跟踪仅针对构建产物,而非源码文件本身。首次编译报错后能继续构建,是因为构建流程中断后,CMake会重新检查未完成的步骤,但这并不等同于主动检测源码变化。
解决方案
1. 添加UPDATE_COMMAND触发源码变更检测
为每个ExternalProject_Add配置UPDATE_COMMAND,通过修改源码目录中关键文件的时间戳,让CMake意识到源码有更新,从而触发重新配置和编译。示例:
ExternalProject_Add(NAME1 PREFIX NAME1 SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/NAME1/src CMAKE_ARGS ... # 保留原有CMAKE_ARGS参数 UPDATE_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_SOURCE_DIR}/NAME1/src/CMakeLists.txt ) ExternalProject_Add(NAME2 PREFIX NAME2 SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/NAME2/src CMAKE_ARGS ... # 保留原有CMAKE_ARGS参数 DEPENDS NAME1 UPDATE_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_SOURCE_DIR}/NAME2/src/CMakeLists.txt )
2. 启用BUILD_ALWAYS强制每次构建
给ExternalProject_Add添加BUILD_ALWAYS ON选项,这样每次执行make都会重新构建该项目。缺点是无论源码是否变更都会触发编译,可能降低构建效率。示例:
ExternalProject_Add(NAME1 PREFIX NAME1 SOURCE_DIR ... CMAKE_ARGS ... BUILD_ALWAYS ON ) ExternalProject_Add(NAME2 PREFIX NAME2 SOURCE_DIR ... CMAKE_ARGS ... DEPENDS NAME1 BUILD_ALWAYS ON )
3. 手动关联源码文件作为依赖
在根CMakeLists.txt中,将项目的源码文件直接关联为ExternalProject目标的依赖,让Makefile能检测到这些文件的变化。示例:
# 收集NAME1的源码文件(可根据实际调整文件类型) file(GLOB_RECURSE NAME1_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/NAME1/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/NAME1/src/*.h ) # 让NAME1目标依赖自身源码文件 add_dependencies(NAME1 ${NAME1_SOURCES}) # 同理处理NAME2 file(GLOB_RECURSE NAME2_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/NAME2/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/NAME2/src/*.h ) add_dependencies(NAME2 ${NAME2_SOURCES})
注意:GLOB_RECURSE无法自动检测新增文件,若有新增源码文件,需要重新执行cmake生成Makefile。
内容的提问来源于stack exchange,提问作者Mr. Tianyao Zheng
相关产品推荐
相关产品推荐

