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

building go binaries for the pi without a toolchain in sight

Cross-compiling a small Go service for an ARM Raspberry Pi from my laptop using GOOS and GOARCH, with no gcc on the target.

A terminal showing a Go build command

I have a little Pi sat in the cupboard collecting sensor readings, and I'd rather not compile on it. The thing has the build performance of a damp sponge, and the whole reason I wrote the collector in Go was so I wouldn't have to.

The good news is that pure Go makes this trivial. No cgo, no gcc, no faffing with a toolchain. You set two environment variables and you're done:

GOOS=linux GOARCH=arm GOARM=6 go build -o collector .

GOARM=6 is the bit people forget. The original Pi and the Zero are ARMv6, so if you build for the default and ship it across you get a binary that won't run. For a Pi 2 or 3 you want GOARCH=arm GOARM=7, and for a Pi 3 on a 64-bit OS it's GOARCH=arm64. Check uname -m on the target if you're not sure.

The one thing that bites you is cgo. The moment you pull in something that needs a C library, the easy route closes and you're back to wrangling a cross-compiler. So I keep the collector dependency-light on purpose. scp the binary across, systemctl restart, done. The build takes under a second on the laptop and the Pi never has to think about it.