Go has some pretty good support/tools for cross-compiling binaries for multiple platforms/architectures. Just check the
$GOARCH env vars listed in the official documentation.
But sometimes, you may need to use some lib/code written in C that hasn't been ported to Go. For this reason, there's cgo, which you can use to call C code from your Go code. And while it can be straightforward to use when you run the binaries on the same platform you used to build them, it can be a bit of a mess when cross-compiling for platforms/architectures that are different.
Though, I hope that if you continue reading, it will become just a little easier.
Throughout this guide, we'll use Docker to build our binaries, so make sure you've installed the following:
You'll also need to enable the experimental features for Docker.
Let's create a go project:
go mod init github.com/my-username/go-cross
NOTE: Make sure you create a project dir for this and run the above command from the root of that dir.
Now let's create a simple
And the C code that the package is referencing:
Now we need a simple cmd that uses the package:
And finally, we need a simple dockerfile to build our
The project dir should end up similar to the following one:
. ├── Dockerfile.hello ├── cmd │ └── hello │ └── main.go ├── go.mod └── pkg └── hello ├── hello.c ├── hello.go ├── hello.h
Let's build the
docker buildx build -f Dockerfile.hello -o type=local,dest=./bin .
If everything went well, you should find the binary in
./bin/. Now just copy it to your target host and run it.
You could also build the binary on your host:
go build -race -o ./bin/hello cmd/hello/main.go
And run it to verify it works:
You can find the above project at rolandjitsu/go-cross. You'll also find how to use and statically link 3rd party libraries and how to setup a simple Github workflow to test the binaries.
That's all folks.