Skip to main content

Go Build

References

caution
  • c-shared
    • runtime: c-shared builds fail with musllibc golang/go#13492
    • windows c-shared requires TDM-GCC
    • Cannot dlclose, offload c-shared golang/go#11100 (Related to VM)
  • aarch64 -> arm64
    • aarch64 is common in Linux environments.
    • Use arm64 for GOARCH.

Environment Variables

EnvNotemacOS
GOENV~/Library/Application Support/go/env
GOCACHE~/Library/Caches/go-build
GOMODCACHE~/go/pkg/mod
GOTOOLDIR
GOMODgo.mod location
GOWORK
GOMAXPROCSMax Thread
GOGC100 (off to disable)
GOOS
GOARCH

Flags and Options

# List all cross-compilation targets
go tool dist list
# Include cgo support status
go tool dist list -json

# Remove mod cache
go clean -modcache

Build Modes (-buildmode)

ModeDescription
archivebuild non-main, .a
c-archivemain+imports, cgo //export
c-sharedmain+imports, cgo //export
defaultmain+non-main, exec, .a
exemain+imports, exec, ignores non-main packages
piemain+imports, exec, pie
pluginmain+imports, plugin, ignores non-main packages
sharednon-main, for -linkshared (deprecated/broken)

Linker Flags (-ldflags)

FlagDescription
-wdisable DWARF generation
-sdisable symbol table
-X 'pkg.Var=Value'add string definition
-linkmode=external
-extldflags "$LDFLAGS"

GC Flags (-gcflags)

FlagDescription
-NDisable optimizations
-lDisable inlining

Common Flags

FlagDescription
-modcacherwNew mod cache rw - allows rm -rf
-trimpathRemove environment paths, reproducible builds
-ldflags "$GOLDFLAGS"
-mod=readonlyDon't update go.mod
-buildmode=pie

Custom Version Variables

Inject version info at build time:

package main

var Version = "dev"
var CommitTime = ""
var CommitID = ""
var BuildTime = ""
DEF_FLAGS="
-X 'wener.me/tools/build.Version=$(git describe --tags --abbrev=0)'
-X 'wener.me/tools/build.CommitID=$(git rev-parse --short HEAD)'
-X 'wener.me/tools/build.CommitTime=$(git log -1 --format=%cd --date=iso8601)'
-X 'wener.me/tools/build.BuildTime=$(date --iso-8601=seconds)'
"
go build -o bin/cli -ldflags "$DEF_FLAGS" ./cmd/cli

Build Constraints (Tags)

//go:build tag
//+build tag1,tag2

// Complex constraints
//go:build (linux && 386) || (darwin && !cgo)

package main
go build -tags "tag1 tag2"

Build constraints documentation

Cross Compilation

# Example cross compilation commands
CC=i586-mingw32-gcc GOOS=windows GOARCH=386 CGO_ENABLED=1 \
go build -v -o myprogram.exe -ldflags="-extld=$CC"

CC=x86_64-pc-linux-gcc GOOS=linux GOARCH=amd64 CGO_ENABLED=1 \
go build -v -o myprogram -ldflags="-extld=$CC"

Docker Builder

Using prometheus/golang-builder for multi-arch builds.

docker pull quay.io/prometheus/golang-builder:arm
docker run --rm -it --entrypoint bash \
--name go-builder quay.io/prometheus/golang-builder:arm

Architecture Levels (GOAMD64)

go 1.18 新增 GOAMD64 环境变量

  • v1 - 默认
  • v2 - CMPXCHG16B, LAHF, SAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3
    • 2009: Nehalem, Jaguar, Intel Atom Silvermont, QEMU
    • amdv2
  • v3 - AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, OSXSAVE
    • 2015 - Haswell, Excavator
    • amdv3
  • v4 - AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL
    • 2017: Skylake-X, Skylake-SP
    • 2022: Zen 4
    • amdv4
  • 参考
# Check support
grep -oE 'avx2|bmi1|bmi2|f16|fma' /proc/cpuinfo | sort -u

FAQ

  • unrecognized command-line option '-marm': Check CC path.
  • arm-none-eabi-gcc: error: unrecognized command-line option '-pthread': Use arm-linux-eabi or manage empty pthread lib.
  • loadinternal: cannot find runtime/cgo: Ensure CGO_ENABLED=1.
  • FATAL: kernel too old: Check target kernel version support in GCC.