CMake中目标关联的add_custom_command总是执行的问题求助
解决:仅在目标实际更新时执行自定义命令
简化场景的问题修复
你当前的核心问题是add_custom_target的依赖声明错误:
add_custom_target(T1 ALL DEPENDS t1.txt T1)
这里把目标T1自身作为依赖,形成了循环依赖,导致CMake每次构建都会判定T1需要重新生成,进而触发绑定的POST_BUILD命令。
另外,POST_BUILD类型的自定义命令绑定到自定义目标时,只要目标被触发(哪怕没有实际文件更新)就会执行。要实现仅当t1.txt更新时才执行追加操作,需要把追加逻辑转化为生成一个标记文件,让T1依赖这个标记文件,而非依赖目标自身或使用POST_BUILD。
修正后的代码:
cmake_minimum_required(VERSION 3.10) project(proj12 NONE) # 生成t1.txt的基础规则 add_custom_command( OUTPUT t1.txt COMMAND echo "Created at `date`" > t1.txt COMMENT "Creating file.." ) # 追加内容并生成标记文件:仅当t1.txt变化时执行 add_custom_command( OUTPUT t1_appended.stamp COMMAND echo "Appended at `date`" >> t1.txt COMMAND touch t1_appended.stamp # 标记操作完成,用于判断是否需要重新执行 DEPENDS t1.txt COMMENT "Appending file.." ) # 伪目标依赖标记文件,确保仅当依赖更新时触发操作 add_custom_target(T1 ALL DEPENDS t1_appended.stamp)
测试效果:
- 首次
make:执行创建和追加命令; - 再次
make:无文件变化,不会执行任何命令。
实际Jar资源问题的适配方案
针对你提到的旧版UseJava模块add_jar资源命名空间错误的问题,同样可以用标记文件思路实现仅当Jar或资源变化时追加资源:
cmake_minimum_required(VERSION 3.10) project(MyJavaProject) find_package(Java REQUIRED) include(UseJava) # 仅编译Java文件生成基础Jar(不包含资源) add_jar(MyJar SOURCES src/com/example/*.java) # 收集所有资源文件 file(GLOB_RECURSE RESOURCES resources/**/*) # 定义追加资源的命令,生成标记文件 add_custom_command( OUTPUT jar_resources_updated.stamp # 用jar命令追加资源到Jar包,注意调整资源的路径映射(按需修改) COMMAND jar uf $<TARGET_FILE:MyJar> -C resources/ . COMMAND touch jar_resources_updated.stamp DEPENDS MyJar ${RESOURCES} # 依赖Jar包和资源文件,任一变化则执行 COMMENT "Adding resources to Jar.." ) # 创建目标确保资源追加操作执行,且仅在依赖变化时触发 add_custom_target(UpdateJarResources ALL DEPENDS jar_resources_updated.stamp) add_dependencies(UpdateJarResources MyJar)
这个方案中,只有当MyJar因Java文件修改而更新,或者资源文件有变动时,才会执行jar uf命令添加资源,避免了每次构建重复执行的问题。
内容的提问来源于stack exchange,提问作者Arjob Mukherjee
相关产品推荐
相关产品推荐

