go语言如何在编译阶段给变量赋值

go语言如何在编译阶段给变量赋值

如何使用”go build -ldflags -X”命令行参数给package变量赋值。

给出一个应用场景:

我们有时候需要在应用程序启动的时候打印出当前binary的版本信息或者编译时间,从而确定具体的binary版本号。

方法1:

首先想到一个办法就是由编译脚本在编译时生产一个go源文件,包含一个变量值,例如:

$ echo "package main; var Version string = \"build-$(date +%Y%m%d)\"" > version.go
$ cat version.go
package main; var Version string = "build-20180531"
$ cat main.go
package main

import (
    "fmt"
)

func main() {
    fmt.Println("version=" + Version)
}
$ go build

$ ./main
version=build-20180531

这个办法存在一个问题,就是version.go文件每次都会新生产,在有源代码版本管理环境下,污染我们的视线:每一次build这个文件就会发生更新。

方法2:

另一个办法,我们可以使用”go build -ldflags -X”参数来保持version.go文件内容不会发生变化。

  • 步骤1:生产一个版本文件

这个go文件只定义了变量Version,而没有赋值。

$ cat version.go 
package main

var Version string
  • 步骤2:在main里面引用变量

main.go和前面的一样。

$ cat main.go
package main

import (
    "fmt"
)

func main() {
    fmt.Println("version=" + Version)
}
  • 步骤3:编译的时候指定变量值
$ go build -ldflags "-X main.Version=1.0.5"
  • 步骤4:运行
$ ./main
version=1.0.5
  • 步骤5:其他格式定义变量
  1. 通过命令行输出。
$ go build -ldflags "-X main.Version=ver-$(date +%Y%m%d)" 
$ ./main 
version=ver-20180531
  1. 通过环境变量
$ VERSION="testv";go build -ldflags "-X main.Version=ver-${VERSION}"    
$ ./main
version=ver-testv
  • 步骤6:另外可以把version变量放在一个包(package)里面

其实和main包里面是一样的,只是指定的package名是具体的package名,而不是main

$ cat main.go
package main

import (
    "fmt"
    "version"
)

func main() {
    fmt.Println("version=" + version.Version)
}

$ cat version/version.go 
package version

var Version string

$ go build -ldflags "-X version.Version=v$(date +%Y%m%d)" -o main
$ ./main 
version=v20180531

参考go build link command文档:https://golang.org/cmd/link/
其中对-X的定义如下,

-X importpath.name=value
    Set the value of the string variable in importpath named name to value.
    Note that before Go 1.5 this option took two separate arguments.
    Now it takes one argument split on the first = sign.
    原文作者:CodingCode
    原文地址: https://www.jianshu.com/p/201a151a64cc
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞