GOROOT is the path where the Go stdlib and tools reside. To make setting up Go easier, the (default) GOROOT is hardcoded in the go binary. Normally it's /usr/local/go, but if you build Go yourself it'll be whatever path you built it in. If you install Go with Homebrew it'll be like /usr/local/Cellar/go/1.6.2/libexec.

So far, so good. When you install a new version of Go, the new go tool will have the new GOROOT hardcoded, and upgrades will be smooth.

But sometimes Go programs need to know what the GOROOT is. And since it's not necessarily an explicit env var, they need to have the compile-time default hardcoded. Problem is, when you upgrade Go and change the GOROOT, the binaries you built before don't get the memo, and will go look for the GOROOT in the old location.

This breaks many static analysis and build tools, like gocode (guess who just spent an hour trying to debug vim autocompletion), guru and gb.


After being bitten one too many times by this, I wrote a tool that goes over all the binaries in $GOPATH/bin, figures out the import path from the DWARF symbols using debug/gosym, and forcefully reinstalls them.

I run it every time I upgrade Go or anyway change the GOROOT.

It has the added benefit of bringing the security fixes and performance improvements of the new Go version to all installed binaries.

Get it at https://github.com/FiloSottile/gorebuild