Skip to content

Instantly share code, notes, and snippets.

@dmorn
Last active May 2, 2020 07:09
Show Gist options
  • Save dmorn/7a4b80b4e46f79a3a8e68abef4545b6e to your computer and use it in GitHub Desktop.
Save dmorn/7a4b80b4e46f79a3a8e68abef4545b6e to your computer and use it in GitHub Desktop.
Notes on cross compiling a Go distribution

If you cannot get Go installed on your device either because a binary distribution is missing or there are not enough resources (ram, disk space) to directly compile it from source, but your target operating system and CPU architecture are supported, you can still do a cross-compilation from a host that has a working Go installation on it! There are some things you have to take care of, I thought it was worth sharing them.

Go compiles itself after version 1.4, probabily you need a different approach if you target a previous version.

From this point on, I'll call host the device where you have Go available, target the one where you would like it to be (in my case a raspberry Pi 2 running FreeBSD).

On the host

First we need to get the source from somewhere (here I'm following the official guide)

$ git clone https://go.googlesource.com/go goroot
$ cd goroot
$ git checkout <target go version> # go1.14 in my case

Then the compilation step

$ cd src # move where the makefiles live
$ env GOOS=<target os> GOARCH=<target cpu arch> ./make.bash # ./make.bat on windows

For me the complete command was

$ env GOOS=freebsd GOARCH=arm GOARM=7 ./make.bash

Instead of make we're supposed to run ./all.{bash or bat} to compile and test the distribution, but we cannot perfom this step here in this case: the binary producted is not suitable for our architecture. We'll test later on the target.

Copy the whole goroot directory to the target.

On the target

goroot contains the go standard library and you'll find the go and gofmt executables inside goroot/bin/<target os>/. Place the executables inside a directory residing in your $PATH, in my case usr/local/bin suits well.

Now, if you try to run go, chances are that it will tell you that $GOROOT is pointing to a non existing directory. This is why that variable's value was filled at compile time to the directory of your go installation. All good, you just have to move the goroot directory in some lib folder, in my case /usr/libexec/go1.14 (note the renaming) and make $GOROOT point to it. Enter usr/libexec/go1.14/test (or where you placed your goroot) and issue a go run run.go to test your installation.

Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment