27

If I compile this program

package main

import (
    "fmt"
    "os"
)

var version = os.Getenv("VERSION")

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

It prints the env var when I run it

VERSION="0.123" ./example
> 0.123

Is there a way to compile the env var into the binary, for example:

VERSION="0.123" go build example.go

Then get the same output when I run

./example

3 Answers 3

38

Go 1.5 and above edit:

As of now, the syntax has changed.

On Unix use:

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

On Windows use:

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

This is what -X linker flag is for. In your case, you would do

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

Edit: on Windows this would be

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

More info in the linker docs.

Sign up to request clarification or add additional context in comments.

8 Comments

+1 Really cool, I didn't know about this. One note: on Windows you have to write go build -ldflags "-X main.Version %VERSION%"
@icza Thanks, added Windows version to the answer.
Compiler complains about the syntax above link: warning: option -X main.Version 0.2 may not work in future releases; use -X main.Version=0.2. Also, I want to point out that you can set a default value when the env variable is not passed in, set var Version = 0.1 in example.go
@Muddz -ldflags "-X a=1 -X b=2".
I can't getting it to work. Not even a simple line as -ldflags "-X main.test=Hello" with a declared var test string is doing anything. When I run my program as an .exe on windows I also log the test variable to a .txt file to see if it works, but ´test` variable is just an empty string
|
15

Ainer-G's answer led me to the right place, but it wasn't a full code sample answering the question. A couple of changes were required:

  1. Declare the version as var version string
  2. Compile with -X main.version=$VERSION

Here's the full code:

package main

import (
    "fmt"
)

var version string

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

Now compile with

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

2 Comments

play.golang.org/p/B3IuewBqY67 example with the behavior I wanted. Notice that go build behaves different to go run?
@Muddz Same basic approach. If you also have a var date string, then compile with -ldflags "-X main.version=$VERSION -X main.date=$DATE"
4

There is an os.Setenv() function which you can use to set environment variables.

So you can start your application by setting the environment variable like this:

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

If you don't want to do this by "hand", you could create a tool for this which would read the current value of the VERSION environment variable and generate a .go source file in your package containing exactly like the code above (except using the current value of the VERSION environment variable). You can run such code generation by issuing the go generate command.

Read the Generating code blog post for more details about go generate.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.