CMake POST_BUILD命令仅在目标变更时执行及多输出支持问题咨询
问题1解答
你对官方文档的理解没有错误:TARGET签名的add_custom_command的POST_BUILD命令,确实仅会在绑定的目标本身被重新构建时执行,目标处于最新状态时不会触发。你遇到的问题来自两个写法错误:
- TARGET签名的
add_custom_command不支持DEPENDS参数,该参数仅属于生成文件的OUTPUT签名add_custom_command,你添加的DEPENDS Example会被直接忽略,完全不生效。 - 你当前的示例存在两个导致每次构建都触发POST_BUILD命令的原因:
- 你使用的
cmake -E copy命令本身不做差异判断,就算命令触发时目标库没有变更,也会执行覆盖操作,看起来像是每次都触发了命令。可以直接替换为cmake -E copy_if_different,仅当源库文件和目标路径下的文件内容不同时才执行复制,完全符合你的需求。 - 你把共享库的输出目录设置到了源码目录(
CMAKE_CURRENT_SOURCE_DIR)下,绝大多数构建工具默认仅跟踪构建目录内的输出文件,源码目录内的文件不会被纳入增量构建的时间戳/哈希校验,导致每次构建时CMake都会判定Example目标过期需要重新构建,自然会触发POST_BUILD命令。建议优先把目标输出目录设置到构建目录CMAKE_CURRENT_BINARY_DIR下,确有同步到源码目录的需求再配合copy_if_different实现。
- 你使用的
修改后的POST_BUILD代码示例:
add_custom_command(TARGET Example POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Example> ${CMAKE_CURRENT_SOURCE_DIR}/new )
问题2解答
add_custom_command是否支持多输出需要分两种场景判断:
- 如果是生成文件的OUTPUT签名:原生支持多输出配置,你可以在
OUTPUT参数后列出所有生成的文件路径,CMake会自动将所有输出文件和命令绑定,任意一个输出文件过期就会触发命令执行,同时其他依赖这些输出文件的目标也可以正确识别依赖关系。 - 如果是绑定目标的TARGET签名(也就是你当前使用的POST_BUILD/PRE_BUILD等场景):本身没有
OUTPUT参数设计,不存在多输出配置的说法。如果你需要在这类命令执行后生成多个可被其他目标依赖的文件,建议改用OUTPUT签名的add_custom_command,或者手动给生成的文件添加GENERATED属性。
内容的提问来源于stack exchange,提问作者Hayk Poghosyan
相关产品推荐
相关产品推荐

