通过cmake获取版本信息的方式
execute_process( COMMAND git rev-parse --short=8 HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} OUTPUT_VARIABLE _GIT_COMMIT ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) add_definitions(-DGIT_COMMIT=\"${_GIT_COMMIT}\") execute_process( COMMAND date +%y%m%d.%H%M WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} OUTPUT_VARIABLE _COMPLITE_TIME ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) add_definitions(-DCOMPLITE_TIME=\"${_COMPLITE_TIME}\") execute_process( COMMAND cat data/config/meta.json COMMAND grep sdk_name COMMAND awk -F "\"" "{print $4}" WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} OUTPUT_VARIABLE _SDK_NAME ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) add_definitions(-DPROJECT_ID=\"${_SDK_NAME}\") execute_process( COMMAND cat data/config/meta.json COMMAND grep sdk_version COMMAND awk -F "\"" "{print $4}" WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} OUTPUT_VARIABLE _SDK_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) add_definitions(-DBASE_VERSION=\"${_SDK_VERSION}\") message(STATUS "PROJECT_ID:${_SDK_NAME}, SDK_VERSION:${_SDK_VERSION}, GIT_COMMIT: ${_GIT_COMMIT}, COMPLITE_TIME: ${_COMPLITE_TIME}")
这段代码是CMake脚本,用于在构建过程中获取一些信息并设置为预处理器定义,以便在C/C++代码中使用。主要包括:Git提交哈希、编译时间、项目ID(SDK名称)和基础版本(SDK版本)。下面逐段解释:
### 1. 获取Git提交哈希
```cmake
execute_process(
COMMAND git rev-parse --short=8 HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE _GIT_COMMIT
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DGIT_COMMIT=\"${_GIT_COMMIT}\")
```
- **作用**:执行Git命令获取当前仓库的最近一次提交的哈希值的前8个字符。
- `COMMAND git rev-parse --short=8 HEAD`:获取当前HEAD的8位短哈希。
- `WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}`:指定命令执行的工作目录为当前CMake文件所在目录。
- `OUTPUT_VARIABLE _GIT_COMMIT`:将命令的标准输出保存到变量`_GIT_COMMIT`中。
- `ERROR_QUIET`:忽略错误输出(即不显示错误信息)。
- `OUTPUT_STRIP_TRAILING_WHITESPACE`:删除输出末尾的空白字符(如换行符)。
- 然后使用`add_definitions`添加一个预处理器定义`GIT_COMMIT`,其值为获取的哈希字符串(用引号括起来)。
### 2. 获取编译时间
```cmake
execute_process(
COMMAND date +%y%m%d.%H%M
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE _COMPLITE_TIME
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DCOMPLITE_TIME=\"${_COMPLITE_TIME}\")
```
- **作用**:执行系统命令`date`获取当前时间,格式为`年月日.时分`(例如:250611.1430表示2025年6月11日14点30分)。
- 注意:这里变量名`_COMPLITE_TIME`可能是拼写错误,应为`_COMPILE_TIME`(编译时间),但代码中保持一致即可。
- 同样,将获取的时间字符串定义为预处理器宏`COMPLITE_TIME`。
### 3. 获取项目ID(SDK名称)
```cmake
execute_process(
COMMAND cat data/config/meta.json
COMMAND grep sdk_name
COMMAND awk -F "\"" "{print $4}"
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE _SDK_NAME
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DPROJECT_ID=\"${_SDK_NAME}\")
```
- **作用**:从`data/config/meta.json`文件中提取`sdk_name`字段的值。
- 使用管道操作:
1. `cat data/config/meta.json`:读取文件内容。
2. `grep sdk_name`:查找包含`sdk_name`的行。
3. `awk -F "\"" "{print $4}"`:以双引号作为字段分隔符,并打印第4个字段(因为JSON格式通常是`"key": "value"`,所以值在第4个字段)。
- 将提取的值存入变量`_SDK_NAME`,并定义为预处理器宏`PROJECT_ID`。
### 4. 获取SDK版本
```cmake
execute_process(
COMMAND cat data/config/meta.json
COMMAND grep sdk_version
COMMAND awk -F "\"" "{print $4}"
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE _SDK_VERSION
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DBASE_VERSION=\"${_SDK_VERSION}\")
```
- **作用**:与上面类似,从同一文件中提取`sdk_version`字段的值。
- 同样使用`cat`、`grep`和`awk`命令提取版本字符串。
- 将提取的值存入变量`_SDK_VERSION`,并定义为预处理器宏`BASE_VERSION`。
### 5. 打印信息
```cmake
message(STATUS "PROJECT_ID:${_SDK_NAME}, SDK_VERSION:${_SDK_VERSION}, GIT_COMMIT: ${_GIT_COMMIT}, COMPLITE_TIME: ${_COMPLITE_TIME}")
```
- 在CMake配置过程中打印状态信息,显示获取到的项目ID、SDK版本、Git提交哈希和编译时间。
### 总结
这段脚本的目的是在构建时动态获取版本控制信息、构建时间和项目元数据,并将它们作为宏定义传递给编译器,这样在C/C++源代码中就可以使用这些宏来记录版本信息。例如,可以在软件中显示版本号和构建时间,便于追踪和调试。
### 注意点:
1. **依赖外部命令**:需要系统中有`git`、`date`、`cat`、`grep`和`awk`命令,且在CMake运行时可用。
2. **文件路径**:`meta.json`文件位于`data/config/`目录下,且相对于`${CMAKE_CURRENT_LIST_DIR}`存在。
3. **错误静默**:使用`ERROR_QUIET`会隐藏可能的错误(如文件不存在或命令不存在),在调试时可能需要去掉该选项以查看错误。
4. **拼写错误**:`_COMPLITE_TIME` 可能是 `_COMPILE_TIME` 的拼写错误,但代码中保持一致即可。
5. **跨平台问题**:`date`命令和管道操作在Unix-like系统(如Linux、macOS)上可用,但在Windows上可能不兼容(除非使用Cygwin/MSYS或Windows Subsystem for Linux)。
如果需要跨平台,可能需要使用CMake内置命令(如`string(TIMESTAMP ...)`)或编写更复杂的脚本来替代部分操作。
这段 CMake 脚本用于在构建过程中动态获取版本和构建信息,并将其定义为 C/C++ 预处理器宏。以下是逐部分解释:
1. 获取 Git 提交哈希
execute_process(
COMMAND git rev-parse --short=8 HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE _GIT_COMMIT
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DGIT_COMMIT=\"${_GIT_COMMIT}\")
-
作用:获取当前 Git 仓库的 8 位短提交哈希
-
命令:
git rev-parse --short=8 HEAD -
输出处理:保存到变量
_GIT_COMMIT,去除末尾空格 -
结果:添加编译器定义
-DGIT_COMMIT="a1b2c3d4"
2. 获取构建时间
execute_process(
COMMAND date +%y%m%d.%H%M
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE _COMPLITE_TIME
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DCOMPLITE_TIME=\"${_COMPLITE_TIME}\")
-
作用:生成格式为
年月日.时分的时间戳 (如250611.1430) -
命令:
date +%y%m%d.%H%M -
注意:变量名
_COMPLITE_TIME可能是拼写错误 (应为COMPILE) -
结果:添加编译器定义
-DCOMPLITE_TIME="250611.1430"
3. 获取项目 ID (SDK 名称)
execute_process(
COMMAND cat data/config/meta.json
COMMAND grep sdk_name
COMMAND awk -F "\"" "{print $4}"
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE _SDK_NAME
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DPROJECT_ID=\"${_SDK_NAME}\")
-
作用:从 JSON 文件中提取 SDK 名称
-
命令链:
-
cat读取文件 -
grep过滤包含sdk_name的行 -
awk以双引号为分隔符提取第 4 个字段 (值)
-
-
示例输入:
"sdk_name": "my_sdk" -
结果:添加编译器定义
-DPROJECT_ID="my_sdk"
4. 获取 SDK 版本
execute_process(
COMMAND cat data/config/meta.json
COMMAND grep sdk_version
COMMAND awk -F "\"" "{print $4}"
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE _SDK_VERSION
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DBASE_VERSION=\"${_SDK_VERSION}\")
-
作用:从 JSON 文件中提取 SDK 版本号
-
流程:与获取项目 ID 相同,但查找
sdk_version字段 -
示例输入:
"sdk_version": "1.2.3" -
结果:添加编译器定义
-DBASE_VERSION="1.2.3"
5. 打印汇总信息
message(STATUS "PROJECT_ID:${_SDK_NAME}, SDK_VERSION:${_SDK_VERSION}, GIT_COMMIT: ${_GIT_COMMIT}, COMPLITE_TIME: ${_COMPLITE_TIME}")
-
输出示例:
PROJECT_ID:my_sdk, SDK_VERSION:1.2.3, GIT_COMMIT: a1b2c3d4, COMPLITE_TIME: 250611.1430
整体作用
在编译时注入以下信息到程序中:
-
版本标识:通过 SDK 名称和版本号
-
精确构建信息:通过 Git 提交哈希
-
构建时间:精确到分钟的时间戳
使用场景
在 C/C++ 代码中可通过预定义宏访问:
printf("Build: %s/%s\n", PROJECT_ID, BASE_VERSION);
printf("Commit: %s\n", GIT_COMMIT);
printf("Time: %s\n", COMPLITE_TIME);
char const* GetVersionName(void) { static char ver[64]; snprintf(ver, sizeof(ver), "%s_%s_%s_%s_%s", PROJECT_ID, MODULE_ID, BASE_VERSION, GIT_COMMIT, COMPLITE_TIME); return ver; }
注意事项
-
跨平台问题:
date/grep/awk是 Unix 工具,Windows 需配置环境 -
依赖文件:要求
data/config/meta.json存在且包含指定字段 -
错误静默:
ERROR_QUIET会隐藏可能的错误 -
拼写问题:
COMPLITE_TIME应为COMPILE_TIME -
构建一致性:这些值在每次构建时动态生成,确保版本信息实时更新
这种模式常用于生成包含精确构建信息的版本标识,特别适用于需要追踪具体构建版本的应用场景(如 SDK 分发、故障排查等)。

浙公网安备 33010602011771号