Ramblings of an aging IT geek
← Ramblings of an aging IT geek
golang

cross-compiling go for the little arm box in the cupboard

A two-line reminder to myself on building Go binaries for a 32-bit ARM single-board computer from an amd64 laptop, and the one flag people forget.

A terminal showing Go code being compiled

I have a small ARM board in the airing cupboard doing nothing but serving a status page, and every time I want to ship a new build to it I forget the incantation and go digging through shell history. So here it is, written down, mostly for me.

Go's cross-compilation is genuinely one of its best features. No toolchain to install, no Docker dance, no apt install gcc-arm-linux-gnueabihf. You set two environment variables and build:

GOOS=linux GOARCH=arm GOARM=7 go build -o statuspage .

GOOS is the target OS, GOARCH is the architecture, and GOARM is the bit everyone forgets. For a Pi-class board you almost always want 7. Leave it off and Go assumes an older ARM variant, which runs but throws away the floating-point performance of the hardware you actually have. For a 64-bit board it's simply GOARCH=arm64 and you drop GOARM entirely.

The one caveat: this all works because the binary is pure Go. The moment you import something that needs cgo (SQLite drivers being the usual culprit), CGO_ENABLED=0 stops being free and you're back to needing a cross-compiler. For this little status page there's no cgo, so it's a clean static binary, scp it across, restart the service, done. Thirty seconds, no cloud build runner, no fuss.