为Golang应用程序添加编译信息
目录
C语言提供预处理器宏供用户在编译期间提供信息,同时内置__FILE__
、__TIME__
等宏。
Golang中没有宏,但我们可以使用go tool link [flags]
提供的选项-X
实现类似的功能。
说明
-X
选项说明如下
-X importpath.name=value
Set the value of the string variable in importpath named name to value.
This is only effective if the variable is declared in the source code either uninitialized
or initialized to a constant string expression. -X will not work if the initializer makes
a function call or refers to other variables.
Note that before Go 1.5 this option took two separate arguments.
该选项将某个字符串变量importpath.name
的值设置为value
。该变量需要满足下面两个条件之一:
- 尚未初始化;
- 初始化为常量字符串表达式的值,不能使用函数或者其他变量初始化。
使用
编写一个简单的Hello World程序
package main
import "fmt"
func main() {
fmt.Printf("Hello, World!\n")
}
使用下面的命令运行
go run main.go
输出为
Hello, World!
增加两个需要在编译期间设置值的变量:Version
和Date
,并设定字符串默认值。
package main
import "fmt"
var (
Version = "Unknown Version"
Date = "Unknown Date"
)
func main() {
fmt.Printf("Hello, World!\n")
fmt.Printf("Version %s\n", Version)
fmt.Printf("Date %s\n", Date)
}
运行输出为
Hello, World!
Version Unknown Version
Date Unknown Date
使用--ldflags
设置link参数,为字符串变量设定新的值。
go run --ldflags "-X main.Version=0.1.0 -X main.Date=2019.05.24" main.go
命令输出如下
Hello, World!
Version 0.1.0
Date 2019.05.24
一个实际的例子
在Makefile中使用shell命令动态获取VERSION
、BUILD_TIME
和GIT_COMMIT
等变量的值
.PHONY: ecflow_checker
VERSION := $(shell cat VERSION)
BUILD_TIME := $(shell date --utc --rfc-3339 ns 2> /dev/null | sed -e 's/ /T/')
GIT_COMMIT := $(shell git rev-parse --short HEAD 2> /dev/null || true)
ecflow_checker:
go build \
-ldflags "-X \"github.com/perillaroc/ecflow-client-go/ecflow_checker/cmd.Version=${VERSION}\" \
-X \"github.com/perillaroc/ecflow-client-go/ecflow_checker/cmd.BuildTime=${BUILD_TIME}\" \
-X \"github.com/perillaroc/ecflow-client-go/ecflow_checker/cmd.GitCommit=${GIT_COMMIT}\" " \
-o bin/ecflow_checker \
ecflow_checker/main.go
参考
可以参考docker cli源码的编译脚本。