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

如何在CMake中为每个编译命令前执行自定义命令

在CMake中为每个源文件编译前绑定自定义命令

完全可行,下面提供两种实现方案,满足你“仅当目标文件需重建时执行自定义命令”且“通过生成表达式传递源文件路径”的需求:

方案一:针对单个源文件绑定独立自定义命令

这种方式灵活性更高,可针对不同源文件配置不同的预处理逻辑,依赖关系清晰。

# 定义源文件列表
set(SOURCES source1.c source2.c main.c)

# 创建目标可执行文件
add_executable(my_app ${SOURCES})

# 遍历每个源文件,绑定预处理命令
foreach(src IN LISTS SOURCES)
    # 获取当前源文件对应的目标文件路径
    get_source_file_property(obj_path ${src} OBJECT_OUTPUTS)
    # 生成唯一的标记文件,用于跟踪预处理命令是否需要执行
    set(marker_file "${CMAKE_CURRENT_BINARY_DIR}/${src}.precompile.marker")

    # 定义自定义预处理命令
    add_custom_command(
        OUTPUT ${marker_file}
        # 这里替换为你的实际自定义命令,用生成表达式传递源文件路径
        COMMAND my_preprocess_tool "$<SHELL_PATH:${src}>"
        # 依赖源文件,只有源文件变化时才重新执行预处理
        DEPENDS ${src}
        COMMENT "正在预处理源文件: ${src}"
        VERBATIM
    )

    # 创建临时目标,关联标记文件的依赖
    add_custom_target(precompile_${src} DEPENDS ${marker_file})
    # 让主目标依赖临时目标,确保编译源文件前先执行预处理
    add_dependencies(my_app precompile_${src})
endforeach()

原理说明

  • 每个源文件对应一个唯一的标记文件,自定义命令仅在源文件变化时重新生成标记文件
  • 目标文件(如source1.o)间接依赖标记文件,因此只有当标记文件更新时,才会触发后续的编译步骤
  • $<SHELL_PATH:>生成表达式用于处理含空格的源文件路径,确保在shell中正确解析

方案二:全局修改编译命令(批量应用)

如果所有源文件的预处理逻辑一致,可通过修改CMake内置的编译命令变量,一次性为所有源文件添加预处理步骤,更简洁高效。

# 保存原始的C语言编译命令
set(ORIGINAL_C_COMPILE_OBJECT ${CMAKE_C_COMPILE_OBJECT})

# 修改编译命令,在正式编译前插入自定义预处理步骤
# <SOURCE>是CMake编译命令中的占位符,代表当前要编译的源文件路径
set(CMAKE_C_COMPILE_OBJECT 
    "my_preprocess_tool \"$<SHELL_PATH:<SOURCE>>\" && ${ORIGINAL_C_COMPILE_OBJECT}"
)

# 定义源文件并创建目标
set(SOURCES source1.c source2.c main.c)
add_executable(my_app ${SOURCES})

原理说明

  • CMAKE_C_COMPILE_OBJECT是CMake用于生成C语言编译命令的模板变量
  • 我们在原始编译命令前插入自定义命令,用<SOURCE>占位符获取当前源文件路径,配合$<SHELL_PATH:>处理路径兼容性
  • 只有当源文件需要重新编译时,整个命令串(预处理+编译)才会执行,满足“按需执行”的要求

注意事项

  1. 替换示例中的my_preprocess_tool为你实际的自定义命令或脚本路径
  2. 如果是C++源文件,需修改CMAKE_CXX_COMPILE_OBJECT变量
  3. 生成表达式$<SHELL_PATH:>适用于大多数平台,若需跨平台兼容,建议保留该表达式处理路径中的特殊字符

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 16:50:43