C 使用 Git 生成編譯版本號

2021-07-23 04:34:12 字數 3905 閱讀 2769

一般而言,我們的軟體版本號通常會包括乙個編譯版本號。如果你的**使用版本控制系統進行管理(很多開發者都是這麼做的),這個編譯版本號可以是我們版本控制系統的提交版本。

如果我們使用 git 進行管理,這個版本號會是乙個 40 位的 sha-1 的雜湊值。不過,要是我們的軟體版本號新增這麼乙個 40 位長的字串,顯然是不合適的。所以我們一般會取前 7 位——如果這樣還不能標識出唯一版本,那麼就取前 8 位等等。不過,手動去修改這個值當然是不合適的,我們有更簡便的方式。這就是本文所要介紹的內容:使用 git 生成這個編譯版本號。

為達到這一目的,我們一般會新建乙個 version.h 檔案,其內容可以是乙個巨集定義:

c++

1

2

3

4

5

6

#ifudef version_h

#define version_h

#define version_number 1.0.0

#endif // version_h

然後在我們的程式中,通過 include 這個 version.h,就可以獲取這個version_number的值;而我們所要做的,就是能夠由程式生成這個巨集的值。這就是思路,下面我們來看看如何實現。

我們需要同 git 進行互動,並且要能夠寫入檔案。最方便的方式是使用 shell 指令碼。這一設想是現實的:首先,linux 天生具有 shell,可以直接使用;其次,windows 雖然沒有 shell,但是如果你要在 windows 下使用 git,就必須安裝乙個模擬環境,msys 或者 cygwin,而這兩個環境都提供了 shell。當然,如果你使用 msysgit 或者其他方式整合 git,那麼就已經提供了這個 shell。因此,為了使用 shell 指令碼,我們無需在擁有 git 的開發環境中額外安裝其他環境。這也是我們提到的這個方法的可取之處。

首先我們要提供乙個「模板」 version.h.template,用於生成 version.h:

c++

1

2

3

4

5

6

#ifudef version_h

#define version_h

#define version_number $full_version

#endif // version_h

我們的目的是能夠自動替換$git_version這個佔位符,從而達到生成 version.h 的目的。

下面就是我們的 shell 檔案。該檔案參考了這段**,在此表示感謝!

shell

12

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

#!/bin/bash

rm-f

src/

version.h

gitrev-

list

head

|sort

>

config

.git

-hash

localver=`

wc-lconfig

.git

-hash

|awk''`

if[$localver

\>1]

;then

ver=

`git

rev-

list

origin

/master

|sort

|join

config

.git

-hash-|

wc-l|

awk''`

if[$ver

!=$localver];

then

ver=

"$ver+$(($localver-$ver))"

fi ifgit

status

|grep-q

"modified:"

;then

ver=

"$m"

fi ver=

"$ver $(git rev-list head -n 1 | cut -c 1-7)"

git_version=r

$ver

else

git_version=

ver=

"x"

firm-f

config

.git

-hash

catversion

.h.template

|sed

"s/\$full_version/$git_version/g"

>

src/

version.h

echo

"generated version.h"

下面來解釋一下這個 shell 指令碼。

第一行,說明是乙個 bash 指令碼。

第二行,強制刪除 src/version.h 檔案。可以想象,這個檔案就是我們要生成的檔案。如果之前已經生成過,我們則將其刪除。

第三行,執行 git 命令。git rev-list head 獲取推送到伺服器內容的提交列表,然後使用管道 | 將其結果傳送給 sort 命令進行排序,之後使用 > 作輸出重定向,生成 config.git-hash 檔案。

第四行,呼叫乙個 shell 命令:使用 wc 計算 config.git-hash 的行數,然後使用 awk 將其輸出到乙個變數 localver 中。

第五行到第十四行,如果 $localver > 1 —— 注意有 > 的轉義;並且,在變數賦值時無需 $ 符號,但是在使用時需要新增 $ —— 那麼使用「git rev-list origin/master | sort | join config.git-hash – | wc -l | awk 『』」對 ver 進行賦值。這一段命令我們前面已經解釋過,這裡不解釋。如果 $ver != $localver,則將 ver 與 localver 拼接在一起。然後我們檢查 git status 是不是 modified,如果是的話則在後面新增乙個 m。然後,我們使用 cut 命令取前七位。最後,我們將這個值賦給 git_version。注意,我們在 $ver 前面增加了乙個 r,當然你也可以不加,根據自己的需要。

第十五行到第十八行,如果 $localver <= 1,則直接給 git_version 和 ver 初始值。

第十九行,刪除 config.git-hash 檔案。

第二十一行,使用 cat 命令開啟模板檔案,利用管道將其傳遞給 sed——乙個無需開啟檔案即可編輯的編輯器——發給 sed 的命令是「s/\$full_version/$git_version/g」,s 代表替換,s/aaa/bbb/ 表示將 aaa 用 bbb 替換,g 表示全域性。注意,這裡的 aaa 是正規表示式,因此,我們在查詢檔案中的 $full_version 的時候,需要將 $ 轉義。而後面的 $git_version 則是取 shell 變數的值。最後輸出重定向到 src/version.h 檔案。

好了,現在執行下 version.sh,如果沒有路徑問題,version.h 已經在 src 目錄下了!

**

git 生成版本號 git describe

如果使用git命令列工具,產生版本號?git describe如果符合條件的tag指向最新提交則只是顯示tag的名字 否則會有相關的字尾來描述該tag之後有多少次提交以及最新的提交commit id。不加任何引數的情況下,git describe 只會列出帶有注釋的tag git describe ...

C 基於編譯時間自動生成版本號

我們希望每次編譯發布程式都有不同的版本號。但是每次編譯都需要修改版本號特別麻煩。本文介紹一種基於編譯時間生成版本號的方法。c c 編譯器會內建有兩個獲取編譯時間的巨集 date 和 time include int main void 輸出 date may 14 2020 time 19 34 5...

CMake生成版本號

cmake生成版本號 金慶的專欄 原來的cmake需要用shell指令碼生成svn版本號,再作為cmake引數傳入。cmake呼叫指令碼示例 bin sh cmake.sh servercoderoot code server coderevnum svn info grep revision aw...