Golang编译-ldflags -X 在vendor中不生效的问题

栏目: Go · 发布时间: 6年前

内容简介:Golang项目在编译链接的时候可以通过 -ldflags -X 来给代码中的变量赋值,然而这天我却遇到了一个诡异的问题……很多应用在 release 时都会给自己打上版本信息,方便使用者查看,比如:而在 golang 中,这样子的需求我们很容易通过 -ldflags -X 来实现。

Golang项目在编译链接的时候可以通过 -ldflags -X 来给代码中的变量赋值,然而这天我却遇到了一个诡异的问题……

版本信息

很多应用在 release 时都会给自己打上版本信息,方便使用者查看,比如:

$ docker version
Client:
 Version:           18.09.0
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        4d60db4
 Built:             Wed Nov  7 00:49:01 2018
 OS/Arch:           linux/amd64
 Experimental:      false
 
Server: Docker Engine - Community
 Engine:
  Version:          18.09.0
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.4
  Git commit:       4d60db4
  Built:            Wed Nov  7 00:16:44 2018
  OS/Arch:          linux/amd64
  Experimental:     false

而在 golang 中,这样子的需求我们很容易通过 -ldflags -X 来实现。

-ldflags -X

在官网 Command link 的说明中,可以通过 -X 来给某 package 的变量赋值:

-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.

我们写个简单的代码来试一下:

package main
 
import "fmt"
 
var Built = "undefined"
 
func main() {
	fmt.Println("Built:", Built)
}

编译的时候给 Built 加上时间:

$ go build -ldflags "-X \"main.Built=`date '+%Y-%m-%d %H:%M:%S'`\"" -o main .
$ ./main
Built: 2019-01-15 21:22:22

可以看到,通过 -X importpath.name=value 的形式即可给指定 package 的变量赋值。更进一步,对于外部的包,我们也可以依葫芦画瓢:

  • 首先创建一个外部的包 package b ,只包含一个 Built 变量,创建文件 version.go :
package b
 
var Built = "undefined"
  • 再修改 main:
package main
 
import (
	"b"
	"fmt"
)
 
func main() {
	fmt.Println("Built:", b.Built)
}
  • 编译:
$ go build -ldflags "-X \"b.Built=`date '+%Y-%m-%d %H:%M:%S'`\"" -o main .
$ ./main
Built: 2019-01-15 23:56:39

一切正常!

然而,一般情况下对于第三方依赖,我们都会使用 vendor 来管理,这时候目录结构就变成了:

./main.go
./vendor/b/version.go

进行同样的编译操作,结果启动main后却输出:

$ go build -ldflags "-X \"b.Built=`date '+%Y-%m-%d %H:%M:%S'`\"" -o main . 
$ ./main
Built: undefined

所以我们的 b.Built 变量没有正常被赋值?

折腾了许久,最后终于搞明白了。Golang 在 1.5 版本时引入了 vendor 属性,并在 1.6 以后版本默认启用,于是查找依赖包的顺序就变成了:

  • 当前包下的 vendor 目录;
  • 向上级目录查找,直到找到src下的 vendor 目录;
  • 查找 $GOPATH 目录;
  • 查找 $GOROOT 目录;

而 -ldflags -X 中的 importpath 其实是相对于 $GOPATH,所以我们 vendor/b 这个包的路径是需要重新指定的。假设我们的项目是位于 src/a/main.go,而编译的时候需要改为:

$ go build -ldflags "-X \"a/vendor/b.Built=`date '+%Y-%m-%d %H:%M:%S'`\"" -o main . 
$ ./main
Built: 2019-01-16 00:07:45

大功告成!

参考:


以上所述就是小编给大家介绍的《Golang编译-ldflags -X 在vendor中不生效的问题》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

伟大创意的诞生

伟大创意的诞生

史蒂文·约翰逊 (Steven Johnson) / 盛杨燕 / 浙江人民出版社 / 2014-8-1 / CNY 52.90

 大家都认得出好创意。印刷机、铅笔、抽水马桶、电池、互联网、GPS、Google——这些都是绝妙的创意。然而,它们是如何产生的?被喻为“科技界的达尔文”的作者,在《伟大创意的诞生》一书中,提供了深具启示意义以及有论证实据的答案。  作者史蒂文•约翰逊以富有感染力、包罗万象的风格游历于多重领域,从神经生物学、都市研究,到网络文化,找出了独特创新背后的7大关键模式,深入人类600年重要发明的......一起来看看 《伟大创意的诞生》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具