C++使用 Git 生成编译版本号
2016-09-26 14:56
162 查看
一般而言,我们的软件版本号通常会包括一个编译版本号。如果你的代码使用版本控制系统进行管理(很多开发者都是这么做的),这个编译版本号可以是我们版本控制系统的提交版本。
如果我们使用 Git 进行管理,这个版本号会是一个 40 位的 SHA-1 的哈希值。不过,要是我们的软件版本号添加这么一个 40 位长的字符串,显然是不合适的。所以我们一般会取前 7 位——如果这样还不能标识出唯一版本,那么就取前 8 位等等。不过,手动去修改这个值当然是不合适的,我们有更简便的方式。这就是本文所要介绍的内容:使用 Git 生成这个编译版本号。
为达到这一目的,我们一般会新建一个 version.h 文件,其内容可以是一个宏定义:
C++
然后在我们的程序中,通过 include 这个 version.h,就可以获取这个
我们的目的是能够自动替换
下面就是我们的 shell 文件。该文件参考了这段代码,在此表示感谢!
Shell
下面来解释一下这个 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 ‘{print $1}’”对 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 目录下了!
Windows 平台注意:如果在 msysgit 下面,可能会有 join 命令找不到。出现这种问题是因为 msysgit 并没有把所有的 shell 命令都安装上去。解决方案是安装完整的 msys 或者 cygwin,然后将其中的 join.exe 放到 %GIT_PATH%/bin 即可。如果你不想或者不会安装庞大的 msys,那么可以按照这里所说的,利用
wget 下载这些命令。然后将其中的 join.exe 放到 %GIT_PATH/bin% 中。如果还有另外的命令找不到,按照这种方法即可。
转自https://www.devbean.net/2011/11/use-git-generate-version-number/
如果我们使用 Git 进行管理,这个版本号会是一个 40 位的 SHA-1 的哈希值。不过,要是我们的软件版本号添加这么一个 40 位长的字符串,显然是不合适的。所以我们一般会取前 7 位——如果这样还不能标识出唯一版本,那么就取前 8 位等等。不过,手动去修改这个值当然是不合适的,我们有更简便的方式。这就是本文所要介绍的内容:使用 Git 生成这个编译版本号。
为达到这一目的,我们一般会新建一个 version.h 文件,其内容可以是一个宏定义:
C++
123456 | #ifudef VERSION_H#define VERSION_H #define VERSION_NUMBER 1.0.0 #endif // 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #!/bin/bash rm-fsrc/version.h gitrev-listHEAD|sort>config.git-hash LOCALVER=`wc-lconfig.git-hash|awk'{print $1}'` if[$LOCALVER\>1];then VER=`gitrev-listorigin/master|sort|joinconfig.git-hash-|wc-l|awk'{print $1}'` if[$VER!=$LOCALVER];then VER="$VER+$(($LOCALVER-$VER))" fi ifgitstatus|grep-q"modified:";then VER="${VER}M" fi VER="$VER $(git rev-list HEAD -n 1 | cut -c 1-7)" GIT_VERSION=r$VER else GIT_VERSION= VER="x" fi rm-fconfig.git-hash catversion.h.template|sed"s/\$FULL_VERSION/$GIT_VERSION/g">src/version.h echo"Generated version.h" |
第一行,说明是一个 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 ‘{print $1}’”对 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 目录下了!
Windows 平台注意:如果在 msysgit 下面,可能会有 join 命令找不到。出现这种问题是因为 msysgit 并没有把所有的 shell 命令都安装上去。解决方案是安装完整的 msys 或者 cygwin,然后将其中的 join.exe 放到 %GIT_PATH%/bin 即可。如果你不想或者不会安装庞大的 msys,那么可以按照这里所说的,利用
wget 下载这些命令。然后将其中的 join.exe 放到 %GIT_PATH/bin% 中。如果还有另外的命令找不到,按照这种方法即可。
转自https://www.devbean.net/2011/11/use-git-generate-version-number/
相关文章推荐
- 使用 Git 生成编译版本号[转载]
- 使用 Git 生成编译版本号
- g++ 编译链接C++代码, 生成与使用静态库和动态库
- NDK学习笔记<七> 使用AndroidStudio本身,编译C/C++文件生成SO文件
- g++ 编译链接C++代码, 生成与使用静态库和动态库
- 本文是关于使用C++调用Matlab编译生成的Dll的说明
- AndroidStudio 2.2.3:编译C++文件、生成so文件及so文件使用
- 【转】使用VisualStudio完成自动化C++代码生成和编译工作(GacUI)
- 在VS项目中通过GIT生成版本号作为编译版本号
- 使用javac编译java文件和使用javah生成C/C++头文件 遇到找不到类的问题
- 使用distcc和ccache缩短C/C++项目编译时间
- 关于Vs 2005 中出现编译通过,但运行时出现“未使用调试信息生成二进制文件”的问题
- 程序集版本最后一位使用SVN版本号的自动生成方法
- google竞赛题SecretSum的另一种C++解法, 使用递归生成代替循环 -- 1
- VC2005编译SQLite,生成WINCE上使用的DLL和Lib
- aix中使用xlc编译生成动态链接库(shared object)(.so)文件的方法
- C++中位结构的使用注意及#pragma预编译指令的作用
- VC2005编译SQLite,生成WINCE上使用的DLL和Lib
- 使用doxygen为C/C++程序生成中文文档(上)
- 使用doxygen为C/C++程序生成中文文档