CMake 笔记 | [30] 配置时记录Git Hash值

注意
本文最后更新于 2024-01-31,文中内容可能已过时。

一、导言

导言
大多数现代源代码存储库都使用**Git作为版本控制系统进行跟踪,提交的Git Hash决定了源代码的状态。因此,为了标记可执行文件,尝试将Git Hash记录到可执行文件中,方法是将哈希字符串记录在一个头文件中,该头文件可以包含在代码中。**

二、项目结构

1
2
3
4
.
├── CMakeLists.txt
├── example.cpp
└── version.hpp.in

https://gitee.com/jiangli01/tutorials/tree/master/cmake-tutorial/chapter6/04

相关源码

version.hpp.in

1
2
3
4
5
#pragma once

#include <string>

const std::string GIT_HASH = "@GIT_HASH@";

example.cpp

1
2
3
4
5
6
7
8
#include "version.hpp"

#include <iostream>

int main() {
  std::cout << "This code has been configured from version " << GIT_HASH
            << std::endl;
}

CMakeLists.txt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)

project(example LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(GIT_HASH "unknown")
find_package(Git QUIET)
if(GIT_FOUND)
  execute_process(
    COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:%h
    OUTPUT_VARIABLE GIT_HASH
    OUTPUT_STRIP_TRAILING_WHITESPACE
    ERROR_QUIET
    WORKING_DIRECTORY
      ${CMAKE_CURRENT_SOURCE_DIR}
  )
endif()

message(STATUS "Git hash is ${GIT_HASH}")

configure_file(
  version.hpp.in
  generated/version.hpp
  @ONLY
)

add_executable(example example.cpp)

target_include_directories(example
  PRIVATE
    ${CMAKE_CURRENT_BINARY_DIR}/generated
)
引用
1
set(GIT_HASH "unknown")

由于Git命令可能会失败(源代码已经分发到Git存储库之外),或者Git在系统上不可用,我们希望为这个变量设置一个默认值。

tips
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
find_package(Git QUIET)
if(GIT_FOUND)
  execute_process(
    COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:%h
    OUTPUT_VARIABLE GIT_HASH
    OUTPUT_STRIP_TRAILING_WHITESPACE
    ERROR_QUIET
    WORKING_DIRECTORY
      ${CMAKE_CURRENT_SOURCE_DIR}
  )
endif()

使用find_package(Git QUIET)来检测系统上是否有可用的Git。如果有(GIT_FOUNDTrue),运行一个Git命令:${GIT_EXECUTABLE} log -1 --pretty=format:%h。这个命令给出了当前提交Hash的简短版本。

当然,这里我们可以灵活地运行Git命令。

要求execute_process命令将结果放入名为GIT_HASH的变量中,然后删除任何尾随的空格。使用ERROR_QUIET,如果Git命令由于某种原因失败,不会停止配置。

三、结果展示

1
2
3
4
5
6
$ mkdir -p build
$ cd build
$ cmake ..
$ cmake --build .
$ ./example
This code has been configured from version 74e4aa9


生成保存git hash的文件

version.hpp

1
2
3
4
5
#pragma once

#include <string>

const std::string GIT_HASH = "74e4aa9";
Buy me a coffee~
支付宝
微信
0%