Golang实践录:生成版本号和编译时间

本文介绍如何在 Golang 中生成和管理版本号及编译时间。

一、起因

笔者手上有几份祖传代码,最早一份90年代末写,次早是 2012 年写的,最新的代码,也是 2016 年写的,版本号倒有,但没有版本管理,虽然看得头大,但也得看。笔者写的程序一般会添加版本号和编译日期时间,也会加上版本控制,以方便追溯和维护。对于 C/C++ 语言,有__DATE____TIME_这两个宏定义,但 Golang 没有,因此加版本号还是额外研究。

二、思路

本文提供2个方法。一是通过编译时加的 ldflags 参数,对变量进行赋赋值;二是通过内嵌 C 语言函数实现。后者可以使用__DATE____TIME_,为了统一,均在脚本中生成日期日期,版本号亦在脚本中指定,因为在脚本中定制方便一些。

三、实现

方法1:Golang变量

准备:

1
2
Version="v1.0"
BuildTime=`date +'%Y-%m-%d %H:%M:%S'`

代码:

1
2
3
4
5
6
7
8
9
var (
trueBuildTime string
trueVersion string
)

func getVersion1() string {
truereturn fmt.Sprintf(" %v build: %v\n", Version, BuildTime)
}

编译:

1
GO111MODULE=on go build -ldflags "-X 'dbtool/cmd.BuildTime=${BuildTime}' -X 'dbtool/cmd.Version=${Version}'" -mod vendor -o dbtool.exe main.go || exit 1

方法2:调用C函数

准备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Version="v1.0"
BuildTime=`date +'%Y-%m-%d %H:%M:%S'`

GIT_VERSION=$Version" build: "$BuildTime

echo "Generated" $VER_FILE "for version:" $GIT_VERSION

echo "#ifndef PROJECT_VERSION_H" > $VER_FILE
echo "#define PROJECT_VERSION_H" >> $VER_FILE
echo "" >> $VER_FILE
echo "#define VERSION_NUMBER \"$GIT_VERSION\"" >> $VER_FILE
echo "" >> $VER_FILE
echo "#endif" >> $VER_FILE

echo "Job done!!"

代码:

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

/*
#include <stdio.h>
#include "version.h"

char* GetVersion()
{
static char buffer[64] = {0};

// 代码中指定版本信息
snprintf(buffer, 64, " %s build: %s %s\r\n", "v1.0", __DATE__, __TIME__);
// 由脚本生成到文件
//snprintf(buffer, 64, " %s\r\n", VERSION_NUMBER);

return buffer;
}
*/
import "C"

// 注:以上代码必须放到 Goalng 正式语句之前,且import "C"后必须空一行

func getVersion() string {
name1 := C.GetVersion()
name := C.GoString(name1)
truereturn fmt.Sprintf(" %v", name)
}

编译:

1
GO111MODULE=on go build -mod vendor -o dbtool.exe main.go || exit 1

四、测试

1
2
$ ./dbtool.exe --version
dbtool.exe version v1.0 build: 2021-04-04 22:42:07

BuildTime 使用 date 命令生成日期,可用默认的形式,如下:

1
2
$ ./dbtool.exe --version
dbtool.exe version v1.0 build: Apr 4 2021 22:47:20

五、维护

需在编译脚本中修改版本号,可手动修改,也可根据 SVN 或 GIT 版本迭代自动生成(散见于笔者多年前的文章)。

六、源码仓库