Skip to content
Latchkey

go build -ldflags: Inject Version Strings in CI

go build -ldflags passes options to the Go linker, most commonly -X to set a package variable (like a version) and -s -w to strip debug info for a smaller binary.

Release pipelines stamp the version and commit into the binary at build time. -ldflags "-X ..." does exactly that without a code change, and -trimpath keeps builds reproducible.

What it does

go build -ldflags forwards a quoted string of flags to the linker. -X importpath.name=value overrides a string variable; -s omits the symbol table and -w omits DWARF debug info; -trimpath (a build flag, not an ldflag) removes absolute paths from the binary.

Common usage

Terminal
go build -ldflags "-X main.version=$(git describe --tags) -s -w" -o app ./cmd/app
go build -trimpath -ldflags "-X 'main.commit=$GIT_SHA'" ./...
CGO_ENABLED=0 go build -ldflags "-extldflags '-static'" ./cmd/app

Flags

FlagWhat it does
-ldflags "-X p.v=val"Set string variable v in package p at link time
-ldflags "-s -w"Strip symbol table and DWARF for a smaller binary
-trimpathRemove local file system paths from the binary
-ldflags "-extldflags '-static'"Pass flags to the external C linker
-o <file>Write the output binary to a path

In CI

Cache the Go build cache (go env GOCACHE, default ~/.cache/go-build) and the module cache (~/go/pkg/mod) keyed on go.sum to speed rebuilds. Use -trimpath for reproducible release binaries. Set CGO_ENABLED=0 for a static, distroless-friendly binary when you have no cgo dependencies.

Common errors in CI

"cannot use -X with non-string variable" means the target is not a string (only string vars can be set). "missing value in -X=...; use -X=name=value" means a malformed -X. "-X main.version: unknown var" means the importpath is wrong (it is the package path, not the file). Static linking with cgo gives "warning: Using 'getaddrinfo' in statically linked applications".

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →