Go

How do you inject a version string at build time with -ldflags? What does this program print?

Question 429HardGo 1.22 to 1.25
package main

import "fmt"

const commit = "none"
var version = "dev"
var built = defaultBuilt()

func defaultBuilt() string { return "unknown" }

func main() { fmt.Println(version, commit, built) }

// go build -ldflags "-X main.version=1.4.0 -X main.commit=abc123 -X main.built=2025-01-01" .

Prints: 1.4.0 none unknown.

  • version works. -X importpath.name=value sets a package-level string variable that is uninitialized or initialized to a constant expression.
  • commit is a constant, which gets inlined at compile time. -X is silently ignored.
  • built is initialized by a function call, which runs at init time and overwrites the linker value. Again there is no error.

Other points:

  • The symbol needs the full import path, for example -X github.com/acme/app/internal/buildinfo.Version=.... Only main uses the short form.
  • A typo is silently ignored.
  • -s -w strips the symbol table and DWARF debug info.
  • Since Go 1.18 you often don't need -X for the commit: debug.ReadBuildInfo() exposes vcs.revision, vcs.time and vcs.modified automatically.

What interviewers want: "string vars only, no consts or computed initializers, full import path, failures are silent."

More on Modules, Packages & Tooling

All 36 Modules, Packages & Tooling questions