Bootstrapping Go From Source

As part of a work project, I needed to make sure the recently-released go 1.6 works correctly on ppc64le. Unfortunately, there’s (as of now) no binary download for POWER8, which means that we’ll need to build it from scratch.

There’s a small catch. Go’s compiler is itself written in go. This leads to an inception-like recursive problem. If you, like me, want the latest go on a platform that is supported, but don’t have a binary, you’re left with an apparent chicken and egg problem of compiling the compiler.

via GIPHY

Go, of course, includes a rather nice method of “boot strapping” go from source. Following along with that link, we need two things:

  1. A system (any system) that already has a functional go implementation
  2. A system that runs the target architecture

In my case, I can easily download a go installer for my mac. After installing it, “bootstrapping” takes only a few commands:

$ export GOROOT_BOOTSTRAP=/usr/local/go
europa : ~/Developer/go/src
$ GOOS=linux GOARCH=ppc64le ./bootstrap.bash
#### Copying to ../../go-linux-ppc64le-bootstrap
#### Cleaning ../../go-linux-ppc64le-bootstrap
#### Building ../../go-linux-ppc64le-bootstrap
##### Building Go bootstrap tool.
----
Bootstrap toolchain for linux/ppc64le installed in /Users/mchollin/Developer/go-linux-ppc64le-bootstrap.
Building tbz.
-rw-r--r-- 1 mchollin staff 47346907 Mar 11 15:19 /Users/mchollin/Developer/go-linux-ppc64le-bootstrap.tbz <== partial victory!
europa : ~/Developer/go/src
$

After a few moments, this results in a “go-linux-ppc64le-bootstrap.tbz” file which we can scp over to our “target” machine. Once we’re logged into our target box, we can easily use the “bootstrap” toolchain to build the real 1.6 go packages by setting the GOROOT_BOOTSTRAP environment variable, extracting a copy of go’s source once again, and running go’s “src/all.bash” script to kick off a build.

tar -xjf go-linux-ppc64le-bootstrap.tbz
export GOROOT_BOOTSTRAP=/workspace/go-master/go-linux-ppc64le-bootstrap
cd /workspace/go-master/go/src
./all.bash
##### Building Go bootstrap tool.
cmd/dist
##### Building Go toolchain using /workspace/go-master/go-linux-ppc64le-bootstrap.
bootstrap/internal/gcprog
...
(have a coffee, this'll take a few moments)
ALL TESTS PASSED <== Victory!
---
Installed Go for linux/ppc64le in /workspace/go-master/go
Installed commands in /workspace/go-master/go/bin
*** You need to add /workspace/go-master/go/bin to your PATH.
Archiving artifacts
Finished: SUCCESS

Go will use the GOROOT_BOOTSTRAP as a minimally-viable tool chain to build the actual compiler, which you can then use to do cool things.

Until our friends over at golang generate a binary for ppc64le, it takes just a few moments to generate a Jenkins build that verifies that the “bootstrap” builds correctly, and that it (itself) can build the latest golang master.

Jenkins Screenshot

Victory!