Setting up Go for cross compilation

Cross compilation is easy with Go and there are numerous articles on how to do it. However, there are some caveats. Specifically the standard library must be built for the lowest common denominator you want to support for each platform. Here’s how I do it for syncthing. This assumes you have a Go source tree checked out into /usr/local/go.

cd /usr/local/go/src
./all.bash        # Build Go for your native architecture/OS
export GOARM=5    # ARMv5 is the lowest supported ARM architecture
GOOS=linux GOARCH=arm ./make.bash --no-clean  # Build linux/arm
export GO386=387  # This disables SSE/SSE2 requirements for 32 bit builds
# Here we build for 32+64 bit platforms
for os in linux windows freebsd ; do
    GOOS=$os GOARCH=386 ./make.bash --no-clean
    GOOS=$os GOARCH=amd64 ./make.bash --no-clean
done
# Now we build for 64-bit only platforms
for os in darwin solaris ; do
    GOOS=$os GOARCH=amd64 ./make.bash --no-clean
done

When this is done, you can use the ./build.sh all command in the syncthing dist. Solaris supports requires Go1.3.

You should install go vet after recompiling Go;

go get code.google.com/p/go.tools/cmd/vet

Compiling the native architecture (amd64 in my case) after the other (386) seems necessary, for some reason I don’t understand. Doing it the other way around in the linux-windows-freebsd loop causes Go not to build the 5g compiler (or build it, but then clean it out). Don’t know why.

You can also check https://github.com/inconshreveable/gonative

1 Like

That’s actually quite interesting. As far as I know the most problematic platform for cross compiles (in terms of annoying DNS behavior etc) is Mac, which I kind of solve by compiling on Mac. But a nice, automated build for all platforms on Linux would be better. I’ll check it out.

Some more interesting stuff:

Cross compilation tools (they have build in support for building toolchain):

Page for cross compiling on-line: http://gobuild.io/