How to Cross-Compile Go for Multiple GOOS and GOARCH
Go cross-compiles natively, so setting GOOS and GOARCH environment variables produces a binary for any target from a single Linux runner.
Pure Go needs no emulation to cross-compile. Drive GOOS and GOARCH from a matrix and one Linux runner can emit every platform binary in parallel.
Steps
- Define a matrix of
goos/goarchinclude entries. - Export
GOOSandGOARCHbeforego build. - Name the output binary with the OS and arch so artifacts stay distinct.
Workflow
.github/workflows/release.yml
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- { goos: linux, goarch: amd64 }
- { goos: linux, goarch: arm64 }
- { goos: darwin, goarch: arm64 }
- { goos: windows, goarch: amd64 }
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
run: go build -o "dist/app-${{ matrix.goos }}-${{ matrix.goarch }}" ./cmd/appGotchas
- Packages that use cgo need
CGO_ENABLED=0or a matching cross C toolchain, or the build fails to link. - Windows targets get an
.exesuffix; add it to the output name for GOOS windows.
Related guides
How to Cross-Compile Rust With --target and crossCross-compile Rust in CI by adding a target with rustup and building with --target, or use the cross tool to…
How to Publish Platform-Specific Artifacts From a MatrixUpload one artifact per OS from a GitHub Actions matrix by suffixing the artifact name with matrix.os, then d…