天天看點

bash: git: command not found_奇技淫巧[1]:cmake中擷取git資訊

bash: git: command not found_奇技淫巧[1]:cmake中擷取git資訊

奇技淫巧[1]:cmake中擷取git資訊

1 目的

擷取目前源碼的git分支名及Commit Hash,将其寫入頭檔案并生成至指定目錄。

2 要點

  • macro

    宏的使用
  • execute_process

    執行一個子程序
  • configure_file

    修改并拷貝檔案

3 用法

工程結構如下:

root
├── CMakeLists.txt
├── cmake
│   └── Utility.cmake
└── include
    └── git_version.h.in
           

首先在CMakeLists.txt中加入自定義cmake檔案目錄,這樣在

include(Utility)

時cmake會自動搜尋并引入

Utility.cmake

[CMakeLists.txt]:

# 添加自定義cmake檔案目錄
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

# 使用Utility.cmake
include(Utility)
           

Utility.cmake

中定義了

get_git_hash

get_git_branch

兩個宏,分别用于擷取目前源碼的Commit Hash及git分支名

[CMakeLists.txt]:

# 擷取目前的GIT_HASH
set(GIT_HASH "")
get_git_hash(GIT_HASH)
message(STATUS "Git hash is ${GIT_HASH}")

# 擷取目前的分支
set(GIT_BRANCH "")
get_git_branch(GIT_BRANCH)
message(STATUS "Git branch is ${GIT_BRANCH}")
           

宏的定義在Utility.cmake中,以

get_git_hash

為例代碼如下,其中

execute_process

exec_program

的新版實作,盡量使用前者以獲得更多特性支援

另:

get_git_branch

隻需将

COMMAND

替換為

${GIT_EXECUTABLE} symbolic-ref --short -q HEAD

即可

[Utility.cmake]:

# get git hash
macro(get_git_hash _git_hash)   # 宏的開始
    find_package(Git QUIET)     # 查找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()
endmacro()                      # 宏的結束
           

在擷取

GIT_HASH

GIT_BRANCH

兩個字元串變量之後,執行

configure_file

,将

git_version.h.in

中的

@GIT_BRANCH@

@GIT_HASH@

進行替換,并儲存為指定路徑下的

git_version.h

[CMakeLists.txt]:

configure_file(
  ${CMAKE_CURRENT_SOURCE_DIR}/include/git_version.h.in  # 輸入
  ${CMAKE_BINARY_DIR}/generate/git_version.h            # 輸出
  @ONLY     # 隻接受形如@VAR@的占位符
  )
           

[http://git_version.h.in]:

#pragma once
#include <string>

const std::string git_branch = "@GIT_BRANCH@";
const std::string git_hash = "@GIT_HASH@";
           

執行

cmake

之後

build

下多了相應的檔案

root
└── build
    ├── ...
    └── generate
        └── git_version.h
           

[git_version.h]:

#pragma once
#include <string>

const std::string git_branch = "master";
const std::string git_hash = "e40f51c";
           

4 源碼

git clone https://github.com/zfrxiaxia/cmake_template_git.git