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

CMake copy_if_different未变更也执行 如何避免解压命令重复运行

问题根源

  1. 无输出绑定的自定义目标默认始终执行
    你用add_custom_target定义的copy_libraries没有关联输出文件,CMake默认会将这类目标标记为每次构建都需要执行,哪怕内部用了copy_if_different只会在文件变更时才真实执行复制操作,目标本身的日志输出、命令触发逻辑都会每次运行,看起来就像copy_if_different没生效。
  2. 解压目标没有绑定依赖变化逻辑
    extract_libraries同样是无输出绑定的全局构建(ALL参数)自定义目标,且依赖了每次都会执行的copy_libraries,所以不管源文件有没有变更,解压命令每次都会触发。

解决方案

调整为用add_custom_command绑定输入输出的依赖关系,让CMake自动根据文件时间戳判断是否需要执行对应操作,修改后的完整代码如下:

set(EXTERNAL_LIB_PATH_SRC "/home/pst/libs/void_lib.tar.gz")
set(EXTERNAL_LIB_PATH_DST "/home/pst/my_app/build/external_libs/void_lib.tar.gz")
set(UNPACK_PATH "/home/pst/my_app/build/external_libs/unpacked/")
# 新增解压标记文件,用于记录上次解压时间
set(EXTRACT_STAMP_FILE "${UNPACK_PATH}/.extract_stamp")

# 定义复制操作的自定义命令,关联源文件和目标文件
add_custom_command(
    OUTPUT ${EXTERNAL_LIB_PATH_DST}
    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${EXTERNAL_LIB_PATH_SRC} ${EXTERNAL_LIB_PATH_DST}
    MAIN_DEPENDENCY ${EXTERNAL_LIB_PATH_SRC}
    COMMENT "Copying external library if changed"
)

# 定义解压操作的自定义命令,依赖复制后的压缩包,仅当压缩包更新时才执行
add_custom_command(
    OUTPUT ${EXTRACT_STAMP_FILE}
    COMMAND ${CMAKE_COMMAND} -E make_directory ${UNPACK_PATH}
    COMMAND ${CCRYPT} -d -k "some_key" ${EXTERNAL_LIB_PATH_DST} -c | ${TAR} -xf - -C ${UNPACK_PATH} -Z
    COMMAND ${CMAKE_COMMAND} -E touch ${EXTRACT_STAMP_FILE}
    MAIN_DEPENDENCY ${EXTERNAL_LIB_PATH_DST}
    COMMENT "Extracting external library if changed"
    VERBATIM
)

# 自定义目标仅依赖解压标记文件,无变更时不会触发
add_custom_target(extract_libraries ALL
    DEPENDS ${EXTRACT_STAMP_FILE}
)

add_dependencies(my_app extract_libraries)

效果说明

  • 仅当源压缩包EXTERNAL_LIB_PATH_SRC发生变更时,才会执行复制操作
  • 仅当复制后的目标压缩包EXTERNAL_LIB_PATH_DST更新时,才会执行解压操作,其余构建场景都会跳过这两步

如果可以明确知道解压后生成的所有文件列表,可将EXTRACT_STAMP_FILE替换为这些解压产物的路径,即可无需额外维护标记文件。

内容的提问来源于stack exchange,提问作者pureofpure

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:18:03