The single best thing about Go, on the days I'm feeling generous towards it, is cross-compilation. I had a small daemon to put on an ARM single-board computer, the kind of underpowered widget where compiling anything locally is an act of patience bordering on faith. With Go you don't. You set two environment variables on your fast laptop and out comes a binary the little box can run.
$ GOOS=linux GOARCH=arm GOARM=7 go build -o sensord ./cmd/sensord
$ file sensord
sensord: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked
That's it. No cross toolchain to install, no sysroot, no --host triplet incantations from the autotools era. The Go toolchain ships every target it supports.
The one thing that trips people up is GOARM. GOARCH=arm means 32-bit ARM, but that family spans a lot of years and instruction set versions. GOARM=7 targets ARMv7 with hardware floating point, which is what most boards from the last decade actually are. Set it too high and the binary illegal-instructions on older hardware; leave it off and Go defaults to a conservative value that runs everywhere but slower. For 64-bit boards the question doesn't arise: use GOARCH=arm64 and there's no GOARM to worry about. Check what you've got with uname -m on the target. If it says armv7l, you want GOARM=7. If it says aarch64, you want arm64.
All of that lovely simplicity holds right up until you import something that uses cgo. The moment a dependency links against C, the pure-Go cross-compile evaporates, because now you need an actual C cross-compiler for the target. SQLite drivers are the usual culprit, as is anything touching the system's DNS resolver in certain configurations.
If you can avoid cgo, avoid it:
$ CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 go build ./...
CGO_ENABLED=0 also gives you a fully static binary, which means no fretting about glibc versions on the target. For a daemon that just talks to sensors and pushes data over the network, that's usually achievable. Swap the cgo SQLite driver for a pure-Go one, use the Go resolver, and you're back to the two-variable life.
When you genuinely can't avoid cgo, you point Go at a cross C compiler:
$ CC=arm-linux-gnueabihf-gcc CGO_ENABLED=1 \
GOOS=linux GOARCH=arm GOARM=7 go build ./...
Now you're installing toolchains and minding glibc again, which is precisely the world Go cross-compilation usually saves you from. So my honest advice: design your ARM-targeting code to keep CGO_ENABLED=0 if you possibly can. The static, dependency-free, copy-it-and-run binary is one of Go's real joys, and it's worth a little effort to keep it.
scp the result over, chmod +x, run it. The board doesn't know it didn't compile anything, and frankly neither do I most of the time.