Example Usage in Dockerfiles
# Standard
RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o app.bin ./cmd
# Slightly smaller
RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-w -s" -o app.bin ./cmd
# With version number
RUN CGO_ENABLED=0 go build -a -ldflags "-X main.buildVersion=$(git describe --tags) -extldflags '-static' -s -w" -o app.bin ./cmd
# With build info
RUN COMMIT_HASH=`git describe --exact-match --abbrev=0 --tags $(git rev-parse HEAD) 2> /dev/null || git rev-parse --short HEAD` && \
BUILD_DATE=`date --iso-8601=seconds` && \
LDFLAGS="-w -s -X main.commitHash=${COMMIT_HASH} -X main.buildDate=${BUILD_DATE}" && \
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="${LDFLAGS}" -o app.bin ./cmd
Variables
GOOS=x
- Popular:
linux
, darwin
- Useful for cross platform builds
GOARCH=x
- Popular:
386
, amd64
and arm
, arm64
- Useful for cross platform builds
- Not all combinations of
GOOS
and GOARCH
are available
CGO_ENABLED=x
- Popular: Just disable it:
0
- Some things are only availabe as C libraries however, and setting it to
1
will be required to compile
- This requires a working C compilation toolchain for the target platform
- Fine tuning might be needed, eg.
CC=aarch64-linux-musl-gccgo
Options
o
- Set name of output binary
a
- Force rebuilding of packages that are already up-to-date
ldflags
- Arguments to pass on each go tool link invocation
w
= Omit the DWARF debugging info
- Standardized debugging data format
- This decreases the output binary file size, but not by much (eg 3.7kb of 25mb)
s
= Omit the DWARF debugging info and the symbol and string tables
s
includes w
but in real life you often see both flags passed
- The main benefit is to make reverse engineering the binary a bit harder, by not leaking info like symbol/function/variable names
- It probably also makes the trace output of a crashed golang executable incomprehensible
x
= Overwrite variable at build time
- Often used to hardcode the build/version number during a CI run
go build -ldflags="-X 'main.Version=v1.0.0'"
assumes a package level variable “Version” exists in the main package
- Sub-packages are accessible via
go build -ldflags="-X 'package_path.variable_name=new_value'"
-extldflags '-static'
- Set space-separated flags to pass to the external linker
- See documentation of that external linker, often the GNU linker
ld
-static
means do not link against shared libraries
Links