Introduction
Go's compiler produces single, statically-linked binaries that run anywhere—no runtime dependencies, no DLL hell, no interpreter needed. This simplicity revolutionizes deployment: copy one file, and it runs. This lesson covers the build process, cross-compilation, and production optimizations.
Key Concepts
Static Binary: An executable containing all dependencies, requiring no external libraries at runtime.
Cross-Compilation: Building binaries for different operating systems and architectures from a single machine.
Build Tags: Conditional compilation directives that include or exclude files based on constraints.
ldflags: Linker flags that inject values at build time or strip debugging information.
Real World Context
Docker images for Go applications can be as small as 5MB (using scratch base images) because the binary is self-contained. CI/CD pipelines can build Linux, Windows, and macOS binaries in parallel from a single codebase. Companies distribute CLI tools as single executables without asking users to install Go.
Deep Dive
Basic Building
bashgo build # Build current package go build -o myapp # Specify output name go build ./cmd/server # Build specific package
Installing Binaries
bashgo install # Install current module go install github.com/user/tool@v1.0 # Install remote tool
Binaries go to $GOBIN (default: $GOPATH/bin).
Cross-Compilation
Set GOOS and GOARCH environment variables:
bash# Common targets GOOS=linux GOARCH=amd64 go build -o app-linux GOOS=darwin GOARCH=arm64 go build -o app-mac-m1 GOOS=windows GOARCH=amd64 go build -o app.exe
Production Build Flags
bash# Strip debug info (smaller binary) go build -ldflags="-s -w" -o myapp # Embed version at build time go build -ldflags="-X main.version=1.0.0" -o myapp # Enable race detector (development only) go build -race -o myapp
Build Tags
go//go:build linux // +build linux package main // This file only compiles on Linux
Common Pitfalls
-
Using
-racein production: The race detector adds significant overhead (10x slower, 10x memory). It's for development only. -
Forgetting CGO implications: Cross-compilation with CGO enabled requires a C cross-compiler. Set
CGO_ENABLED=0for pure Go builds. -
Not stripping binaries: Production binaries include debug symbols by default, making them 30-50% larger than necessary.
Best Practices
- Use
-ldflags="-s -w"for production to reduce binary size. - Embed version information using
-ldflags="-X main.version=$(git describe)". - Create a Makefile or build script for reproducible multi-platform builds.
- Test cross-compiled binaries on target platforms before release.
Summary
Go produces statically-linked binaries using go build. Cross-compilation is achieved by setting GOOS and GOARCH. Use go install for tools and -ldflags for production optimizations. Build tags enable platform-specific compilation.
Code Examples
# Cross-compile for multiple platforms
GOOS=darwin GOARCH=arm64 go build -o myapp-mac-arm64
GOOS=linux GOARCH=amd64 go build -o myapp-linux-amd64
GOOS=windows GOARCH=amd64 go build -o myapp.exe