C语言想要 -v 显示编译时间,可以使用 _DATE_, _TIME_ 这两个宏,
而 Go 没有类似的常量,当然可以使用 Go 调用 C 代码(这是另一种方法)
然而,更好的方法是使用 go build 的 -ldflags 参数
原理如下:
$ go build --help
-ldflags 'flag list'
arguments to pass on each go tool link invocation.
$ go tool link --help
-X definition
add string value definition of the form importpath.name=value
也就是可以在编译Go程序时,添加指定包的指定变量
----------------------------- 项目示例分割线 ----------------------------
完整项目见 github
version/version.go:
package version
import (
"fmt"
"os"
)
var (
BuildVersion string
BuildTime string
BuildName string
)
func init() {
args := os.Args
if nil == args || len(args) < 2 {
return
}
if "-v" == args[1] {
fmt.Printf("%s: v%s (%s)\n", BuildName, BuildVersion, BuildTime)
} else if "-h" == args[1] {
fmt.Println("Usage:")
fmt.Printf("./%s\n", BuildName)
fmt.Printf("./%s -v\n", BuildName)
fmt.Printf("./%s -h\n", BuildName)
}
os.Exit(0)
}
makefile:
BUILD_VERSION := 1.0.0
BUILD_TIME := $(shell date "+%F %T")
BUILD_NAME := go-version-sample
SOURCE := ./*.go
TARGET_DIR := /path-you-want/${BUILD_NAME}
all:
go build -ldflags \
"-X ${BUILD_NAME}/version.BuildVersion=${BUILD_VERSION} \
-X '${BUILD_NAME}/version.BuildTime=${BUILD_TIME}' \
-X ${BUILD_NAME}/version.BuildName=${BUILD_NAME}" \
-o ${BUILD_NAME} ${SOURCE}
clean:
rm ${BUILD_NAME} -f
install:
# mkdir -p ${TARGET_DIR}
# cp ${BUILD_NAME} ${TARGET_DIR} -f
.PHONY : all clean install ${BUILD_NAME}
makefile 文件中定义了 version 包中的 BuildTime 等变量,
然后在 version 包的 init() 函数中使用
(还可以添加 COMMIT_SHA1=`git rev-parse HEAD` 类似的变量)
main.go:
package main
import _ "go-version-sample/version"
import (
"fmt"
)
func main() {
fmt.Println("From main(): hello")
}
这里把 version 包的引用放在最前面,好处是程序第一时间检查参数,-v 显示版本号后直接退出程序(包的初始化是按照声明顺序)。
否则程序会执行其他包不必要的初始化(比如mysql连接)
(不把变量放到main包也是同样的道理,因为main总会包含其他包)
最后,使用 make, make clean, make install 命令就可以使用了