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

CMake自定义目标配置:输出数量变化时避免无意义重建

解决方案

问题根源在于CMake会将add_custom_command的COMMAND内容作为构建触发条件的一部分,只要命令行参数变化,即使输出文件未过时,也会重新执行目标。要实现仅当输出文件过时才运行,需要让COMMAND固定不变,同时让脚本根据CMake配置阶段生成的标志来决定是否生成额外输出。

修改步骤

1. 调整CMakeLists.txt

  • 在配置阶段生成标志文件,告知脚本是否需要生成bar.txt
  • 固定add_custom_command的命令行,避免随MORE_OUTPUT参数变化
  • 让自定义目标依赖所有输出文件,确保开启额外输出时能正确检查bar.txt

修改后的CMakeLists.txt:

cmake_minimum_required(VERSION 3.14)
project(example VERSION 1.0.0 LANGUAGES )

# 生成标志文件,存放于构建目录,避免污染源码目录
set(GENERATE_BAR_FLAG ${CMAKE_CURRENT_BINARY_DIR}/generate_bar.flag)
if(NOT MORE_OUTPUT STREQUAL "")
    file(WRITE ${GENERATE_BAR_FLAG} "1")
else()
    if(EXISTS ${GENERATE_BAR_FLAG})
        file(REMOVE ${GENERATE_BAR_FLAG})
    endif()
endif()

# 定义输出文件列表
list(APPEND outputs ${CMAKE_CURRENT_SOURCE_DIR}/foo.txt)
if(NOT MORE_OUTPUT STREQUAL "")
    list(APPEND outputs ${CMAKE_CURRENT_SOURCE_DIR}/bar.txt)
endif()

add_custom_command(
    DEPENDS something.txt
    OUTPUT  ${outputs}
    # 命令行固定,仅传递标志文件路径(路径不随MORE_OUTPUT变化)
    COMMAND ./file_generator.sh ${GENERATE_BAR_FLAG}
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
)

# 目标依赖所有输出文件,确保开启MORE_OUTPUT时bar.txt被正确处理
add_custom_target(EXAMPLE ALL DEPENDS ${outputs})

2. 修改file_generator.sh

  • 不再依赖命令行参数,改为检查标志文件是否存在来决定是否生成bar.txt

修改后的file_generator.sh:

#!/bin/bash
GENERATE_BAR_FLAG="$1"

# 确保foo.txt始终更新
touch foo.txt

# 仅当标志文件存在时生成bar.txt
if [ -f "${GENERATE_BAR_FLAG}" ]; then
    touch bar.txt
fi

效果验证

  • 当something.txt未修改,且输出文件(foo.txt及开启MORE_OUTPUT时的bar.txt)已存在且最新时,无论MORE_OUTPUT参数如何变化,目标都不会重新执行
  • 当something.txt修改,或输出文件不存在时,目标会执行脚本,根据标志文件决定是否生成bar.txt
  • 切换MORE_OUTPUT参数后,若新增的输出文件(如bar.txt)不存在,CMake会触发脚本生成该文件,符合预期

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 22:54:52