How to Cross-Compile Go Programs for Different OS and Architecture

Cli
To cross-compile Go programs, simply set the `GOOS` and `GOARCH` environment variables before running `go build`, or pass them as flags directly to the command.

To cross-compile Go programs, simply set the GOOS and GOARCH environment variables before running go build, or pass them as flags directly to the command. This allows you to build binaries for any supported operating system and CPU architecture from a single machine without needing the target environment installed.

For a quick one-off build, use the flags directly in the terminal. For example, to compile a Linux binary for an AMD64 machine from a macOS host:

GOOS=linux GOARCH=amd64 go build -o myapp-linux ./cmd/myapp

If you need to build for multiple targets simultaneously (e.g., Linux, Windows, and macOS for both AMD64 and ARM64), a simple shell loop is the most efficient approach:

for os in linux windows darwin; do
  for arch in amd64 arm64; do
    GOOS=$os GOARCH=$arch go build -o myapp-$os-$arch ./cmd/myapp
  done
done

When targeting specific architectures like ARM (common for Raspberry Pi or AWS Graviton instances), ensure you use the correct GOARCH value. Use arm for 32-bit ARM and arm64 for 64-bit ARM. For older 32-bit ARM devices, you may also need to set GOARM to specify the instruction set version (e.g., GOARM=7 for ARMv7):

GOOS=linux GOARCH=arm GOARM=7 go build -o myapp-linux-arm ./cmd/myapp

Be aware that cross-compilation works seamlessly for pure Go code. However, if your project uses cgo to link against C libraries, you must install the corresponding C compiler and headers for the target OS on your build machine. For instance, building a Linux binary with cgo on macOS requires installing the gcc toolchain for Linux via a cross-compiler setup or using a Docker container that matches the target environment. If you encounter build errors related to missing headers or libraries while using cgo, disable it temporarily with CGO_ENABLED=0 to verify if the issue is C-specific:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o myapp ./cmd/myapp

Always test the resulting binary in a container or virtual machine matching the target OS to ensure runtime compatibility, especially if your application relies on system-specific behaviors or file paths.