Stage 1 · Code
Your First Real Program
Build & Ship a Binary
Compile a release binary with version metadata, cross-compile for multiple platforms, and distribute it as a single file.
go build Basics
go build compiles your module into a native executable. The binary is statically linked and requires no runtime, no interpreter, and no external libraries — just copy it and run it.
# Build the main package (cmd/tasker)
go build -o tasker ./cmd/tasker
# Run it
./tasker --help
# Verify it is truly static
file tasker
# tasker: ELF 64-bit LSB executable, statically linkedThe -o tasker flag names the output binary. On Windows the default name is tasker.exe. The binary is self-contained — you can copy it to any machine with the same OS and CPU architecture.
Version Metadata with ldflags
-ldflags passes linker flags. The -X flag sets the value of a package-level string variable at link time — the standard way to embed version, commit hash, and build date into a binary without modifying source code.
VERSION=$(git describe --tags --always --dirty)
COMMIT=$(git rev-parse --short HEAD)
DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
go build \
-ldflags="-X main.version=${VERSION} -X main.commit=${COMMIT} -X main.buildDate=${DATE}" \
-o tasker \
./cmd/tasker
./tasker --version
# tasker v1.2.0 (commit=abc1234 built=2024-03-15T10:00:00Z)git describe --tags --always --dirty produces a version string like v1.2.0 for tagged releases or v1.2.0-3-gabc1234-dirty for untagged commits. This gives every binary a unique, traceable identity.
Cross-Compilation
Set GOOS and GOARCH to build for any supported platform. Go supports over 45 OS/architecture combinations without any cross-compiler toolchain.
# Build for all major platforms with a loop
BINARY=tasker
VERSION=v1.0.0
for GOOS in linux darwin windows; do
for GOARCH in amd64 arm64; do
EXT=""
[ "$GOOS" = "windows" ] && EXT=".exe"
OUTPUT="${BINARY}_${GOOS}_${GOARCH}${EXT}"
GOOS=$GOOS GOARCH=$GOARCH go build -o "$OUTPUT" ./cmd/tasker
echo "built $OUTPUT"
done
done
# Result:
# tasker_linux_amd64
# tasker_linux_arm64
# tasker_darwin_amd64
# tasker_darwin_arm64
# tasker_windows_amd64.exe
# tasker_windows_arm64.exeSix binaries, one command loop, no cross-compiler setup. This is one of Go's most practical production advantages — a single developer machine can build release artifacts for every platform.
Distributing the Binary
mkdir -p dist
# Compress each binary
for f in tasker_*; do
if [[ $f == *windows* ]]; then
zip dist/${f%.exe}.zip $f
else
tar czf dist/${f}.tar.gz $f
fi
done
# Generate SHA-256 checksums
cd dist
sha256sum *.tar.gz *.zip > checksums.txt
cat checksums.txtUsers verify downloads with sha256sum -c checksums.txt. Distributing checksums alongside binaries lets users confirm they downloaded an unmodified build.
A Go binary has no runtime dependencies, no shared libraries to install, no PATH concerns, no version conflicts. For SRE tools and internal utilities, this means zero installation friction — download, chmod +x, run. This is why Go dominates the tooling space in platform engineering.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.