将Golang编译环境变量编译进二进制文件

26

如果我编译这个程序

package main

import (
    "fmt"
    "os"
)

var version = os.Getenv("VERSION")

func main() {
    fmt.Println(version)
}

运行时它会打印环境变量

VERSION="0.123" ./example
> 0.123

有没有一种方法可以将环境变量编译到二进制文件中,例如:

VERSION="0.123" go build example.go

当我运行时,得到了相同的输出

./example
3个回答

36

Go 1.5 及以上版本编辑:

现在,语法已经发生了变化。

在 Unix 上使用:

go build -ldflags "-X main.Version=$VERSION"

在Windows上使用:

go build -ldflags "-X main.Version=%VERSION%"

这就是使用-X链接器标志的原因。在您的情况下,您应该执行以下操作:


go build -ldflags "-X main.Version $VERSION"

编辑:在Windows上这将是

go build -ldflags "-X main.Version %VERSION%"

了解链接器文档中的更多信息.


2
+1 真的很酷,我不知道这个。需要注意的是,在Windows上你必须写成 go build -ldflags "-X main.Version %VERSION%" - icza
1
@icza 谢谢,已将 Windows 版本添加到答案中。 - Ainar-G
1
编译器报错,指出上面的语法存在问题:link: warning: option -X main.Version 0.2 may not work in future releases; use -X main.Version=0.2。此外,我想指出,当环境变量未传递时,您可以设置默认值,在 example.go 中设置 var Version = 0.1 - mozey
1
我无法让它工作。甚至使用声明的var test string的简单行-ldflags“ -X main.test = Hello”也没有任何作用。当我在Windows上运行我的程序作为.exe时,我还将test变量记录到.txt文件中以查看它是否有效,但是test变量只是一个空字符串。 - user9591909
这是一个很酷的技巧,我之前不知道。谢谢。但问题是如何在构建时设置环境变量。有人有正确的答案吗? - srini
显示剩余3条评论

13

Ainer-G的答案引导我到了正确的地方,但那不是一个完整的代码示例来回答问题。需要进行一些更改:

  1. 将版本声明为var version string
  2. 使用-X main.version=$VERSION进行编译

以下是完整的代码:

package main

import (
    "fmt"
)

var version string

func main() {
    fmt.Println(version)
}

现在使用以下命令进行编译

go build -ldflags "-X main.version=$VERSION"

https://play.golang.org/p/B3IuewBqY67 是我想要的行为示例。请注意,go build 的行为与 go run 不同? - mozey
1
@Muddz 同样的基本方法。如果你也有一个 var date string,那么使用 -ldflags "-X main.version=$VERSION -X main.date=$DATE" 进行编译。 - Cody A. Ray

4

有一个os.Setenv()函数,您可以使用它来设置环境变量。

因此,您可以通过设置环境变量来启动应用程序,就像这样:

func init() {
    os.Setenv("VERSION", "0.123")
}

如果您不想手动操作,可以创建一个工具来完成此任务。该工具将读取当前 VERSION 环境变量的值,并在您的包中生成一个 .go 源文件,其内容与上面的代码完全相同(只是使用 VERSION 环境变量的当前值)。您可以通过发出 go generate 命令来运行这样的代码生成。
阅读生成代码博客文章,了解更多关于 go generate 的详细信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接