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

为何CMake add_custom_command()中执行git rev-parse命令失败?

CMake中add_custom_command读取Git提交哈希失败的原因与解决方法

问题差异解析

你遇到的核心问题是错误使用了add_custom_command不支持的OUTPUT_VARIABLE参数——这个参数是execute_process的专属选项,add_custom_command根本不识别它,因此会把OUTPUT_VARIABLE GIT_COMMIT_HASH当成git rev-parse HEAD命令的额外参数传递给Git,导致Git将GIT_COMMIT_HASH视为文件路径,进而报错“该路径不存在”。

而第一个命令看似正常运行,只是巧合:git tag --points-at HEAD GIT_TAG这个语法本身合法(Git会把GIT_TAG当作要校验的标签名,若仓库中不存在该标签,Git仅返回空结果但不抛出错误),但实际上也没有将标签结果存入GIT_TAG变量,你只是误以为它成功了。

解决方法

根据需求场景,有两种正确的实现方式:

1. 配置阶段获取Git信息(常用)

如果只需要在CMake配置时获取一次Git哈希和标签,直接用execute_process即可,它支持OUTPUT_VARIABLE参数捕获命令输出:

# 获取提交哈希
execute_process(
    COMMAND git rev-parse HEAD
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    OUTPUT_VARIABLE GIT_COMMIT_HASH
    OUTPUT_STRIP_TRAILING_WHITESPACE  # 去除末尾换行符
)

# 获取指向HEAD的标签
execute_process(
    COMMAND git tag --points-at HEAD
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    OUTPUT_VARIABLE GIT_TAG
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

# 可选:打印验证
message(STATUS "当前Git提交哈希: ${GIT_COMMIT_HASH}")
message(STATUS "指向HEAD的Git标签: ${GIT_TAG}")

2. 构建阶段实时获取Git信息

如果需要每次构建时都获取最新的Git提交(比如配置后代码有新提交),可以通过add_custom_target生成临时文件,再读取文件内容:

# 构建时执行Git命令,将哈希写入临时文件
add_custom_target(update_git_hash ALL
    COMMAND ${CMAKE_COMMAND} -E echo "$(git rev-parse HEAD)" > ${CMAKE_BINARY_DIR}/git_hash.txt
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    COMMENT "获取最新Git提交哈希"
)

# 读取文件内容到变量(若要让代码编译时能使用,建议结合configure_file生成头文件)
file(READ ${CMAKE_BINARY_DIR}/git_hash.txt GIT_COMMIT_HASH)
string(STRIP ${GIT_COMMIT_HASH} GIT_COMMIT_HASH)

# 示例:生成头文件供代码调用
configure_file(
    ${CMAKE_SOURCE_DIR}/version.h.in
    ${CMAKE_BINARY_DIR}/version.h
    @ONLY
)

对应的version.h.in内容:

#define GIT_COMMIT_HASH "@GIT_COMMIT_HASH@"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 02:23:18