You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 15:01:04