== Building the Go compiler from source from scratch (on Unix) Unlike [[some languages https://www.rust-lang.org/en-US/]] which are a real tedious pain to build from source, [[Go https://golang.org/]] is both easy and interesting to build from source, even (and especially) for the latest development version. Building from source can be especially convenient if you want your own personal copy of a current version of Go (or the very latest version) on a system where you don't have permissions required to install system packages or write to _/usr/local_. I've seen various recipes for building Go this way, but here is the one I now recommend that you use, with some commentary on why I'm doing it this way. First off, to build Go you need a working C compiler environment and a reasonably current version of _git_. Arranging for these is beyond the scope of these instructions; I'm just going to assume that you can build programs in general. Building current versions of Go also requires a working Go compiler, so the from scratch process of building Go from source needs another working Go compiler. The easiest and currently best source of this second Go compiler is a prebuilt pacakge from the Go people. My process goes like this: .pn prewrap on # Make a bootstrap area that you'll use for the bootstrap Go compiler, and fetch the latest prebuilt Go 1.8 package from [[the official Go downloads area https://golang.org/dl/]]: > mkdir bootstrap > cd bootstrap > wget https://.../.tar.gz > tar -xf .tar.gz You specifically want Go 1.8 (1.8.1 as I write this) because Go compile times took a nose dive from Go 1.5 onwards (the first version of the compiler that was written in Go instead of C) and only recently recovered. It used to be clearly slower to bootstrap Go with versions of Go from 1.5 onwards, but it's now actually slightly faster to do so with Go 1.8.1 instead of with Go 1.4, at least on 64-bit Linux x86. (I wound up testing this as part of writing this entry and surprised myself. I used to use Go 1.4 as the bootstrap compiler; I'm now switching to Go 1.8. A quick test suggest that Go 1.7 is also slightly faster than Go 1.4 for this, but Go 1.8 is faster than Go 1.7 so you might as well use it.) If your system already has a system version of Go 1.8, you can use that. If the latest version of Go is more recent than Go 1.8 (on your system or released by the Go people or both), it might be better for this. Go 1.9 is probably going to compile Go programs faster than Go 1.8, but predicting the future beyond it is hard. # Get a Git clone of the current master repository: > cd /some/where > git clone https://go.googlesource.com/go go # Create a little script to build your master version of Go using the version of Go in the bootstrap area; this script lives in _go/src_. I call my script _make-all.bash_, and a simple version looks like this: > #!/bin/bash > GOROOT_BOOTSTRAP=/some/where/bootstrap/go > export GOROOT_BOOTSTRAP > ./all.bash You can do this by hand but it gets to be a pain to remember the correct setting for (($GOROOT_BOOTSTRAP)) and [[scripts capture knowledge ../sysadmin/ScriptsRemember]]. If you're using a system version of Go instead of your own bootstrap version, the (($GOROOT_BOOTSTRAP)) setting you want is: > GOROOT_BOOTSTRAP=$(/usr/bin/go env GOROOT) Or perhaps _/usr/local/bin/go_, or even _/usr/local/go/bin/go_. # Build the latest version of Go with this script: > cd go/src > ./make-all.bash You can now add _/some/where/go/bin_ to your path, or symlink the programs there into _$HOME/bin_ if you prefer. (As with most compilers, Go does a two-stage build; first it builds itself with your bootstrap Go, and then it rebuilds itself with itself.) When you want to (re)build the latest version of Go, you simply '_git pull_' to update the master tree and then repeat step four. Future versions of Go will make all of this somewhat easier because they'll permit you to download prebuilt binaries but put them anywhere you want without hassles. Today, it requires somewhat awkward gyrations to download [[one of the distribution packages https://golang.org/dl/]] but not put it in _/usr/local/go_, which creates more than one reason to build your own version of Go from source. === Sidebar: Building specific versions of Go Since the development tree sometimes breaks or has things in it that you don't actually want to use, you may also want to keep around your own copy of, say, the latest officially released Go version, which is Go 1.8.x as I write this. You can do this as a Git worktree derived from your master _go_ repository: > cd /some/where/go > git worktree add -b release-branch.go1.8 ../v1.8 origin/release-branch.go1.8 > cd ../v1.8/src > cp ../go/src/make-all.bash . > ./make-all.bash ('_git branch -r_' in your _go_ repo will be useful here. I believe this tree can be updated when the Go people release new updates for Go 1.8, although I'm not completely sure of the best Git way to do it.) This is different from the binary release that you downloaded to _/some/where/bootstrap/go_, because it doesn't require any weird steps to use. You can just add _/some/where/v1.8/bin_ at the start of your (($PATH)) and then everything just works, unlike the bootstrap copy, which requires you to set (($GOROOT)) to use it. By the way, yes, once you build your own version of Go 1.8, you can use it as the bootstrap compiler for the latest development version of Go. (Even more recursive setups are possible. My version of Go 1.8 that I'm now using as my bootstrap Go compiler was actually bootstrapped with the latest Go development version, because why not.)