I’ve seen a lot of questions asked about $GOPATH and installing Go for the first time. $GOPATH is simply where Go will look for dependencies to build your application. Python has virtualenv. I don’t really know Java, but it has $JAVA_HOME. These are tools to setup your workspace for a project so the compiler knows where to find dependencies.
This is all that $GOPATH is. It specifies a workspace for your application. You can set a different $GOPATH for different applications to separate build dependencies. You can read about it on the Go website. That link is only referenced from the bottom of the Install instructions. Maybe a relocation would reduce the number of questions coming through.
When I install Go, I grab the binary download from the website. I create a ~/golang directory, and I untar into that directory.
mkdir ~/golang cd ~/golang wget https://storage.googleapis.com/golang/go1.3.1.linux-amd64.tar.gz tar -xzf go1.3.1.linux-amd64.tar.gz
Now I setup my Go binary path. I do this using the $GOROOT and $PATH environment variables. In order to make these variables persist through logins/reboots/etc, I add the following lines to my ~/.bashrc file:
export GOROOT=$HOME/golang/go export PATH=$PATH:$GOROOT/bin
You can also copy/paste these lines into your command prompt to make these changes active right away. You should be able to run `go` now. But this is only half the setup. We need to setup $GOPATH. I think the best way to explain this is with an example:
rday@rday-laptop:~/golang$ mkdir packages1 rday@rday-laptop:~/golang$ export GOPATH=~/golang/packages1/ rday@rday-laptop:~/golang$ go get github.com/rday/web rday@rday-laptop:~/golang$ ls packages1/src/github.com/ rday rday@rday-laptop:~/golang$ mkdir packages2 rday@rday-laptop:~/golang$ export GOPATH=~/golang/packages2/ rday@rday-laptop:~/golang$ go get github.com/alphazero/Go-Redis rday@rday-laptop:~/golang$ ls packages2/src/github.com/ alphazero rday@rday-laptop:~/golang$
What just happened? Why did “go get” place those packages in different locations?
Go is storing our package dependencies in our $GOPATH workspace. When Go builds your application, Go will use the dependencies in whatever workspace your $GOPATH is set to. When $GOPATH is set to ~/golang/packages1, Go stores our package there. When we change $GOPATH, and grab a new package, our new package is stored in the new $GOPATH directory. So in our example, each directory only has 1 package, even though we’ve installed two packages (web.go and Go-Redis). Each package was installed in a separate location, and can only be accessed when $GOPATH points to the correct location.
Why does an environment variable control you package dependency location? Well, it allows you to:
- Have different versions of libraries built with different applications that you create.
- Make custom modifications to packages that only affect one application that you build.
- Distribute build environments to other developers on your team, without mucking up their current environment.
Notice that we haven’t mentioned $GOROOT for a little while. $GOROOT deals with the Go binaries and standard library, the Go language itself. $GOPATH has to do with packages that you work with when building applications.
You can do a lot of different things at this point.
- Modify your ~/.bashrc file and export GOPATH, just as you did with GOROOT.
- Export GOPATH manually each time you work with a different application.
- Source a file that will set your build environment (and $GOPATH) in your app’s root directory
Let’s do one final experiment and install the Go tour.
$ export PATH=$GOPATH/bin:$PATH $ go get code.google.com/p/go-tour/gotour $ ls packages2/bin/ gotour $ gotour 2012/09/29 10:28:46 Serving content from /home/rday/go/packages2/src/code.google.com/p/go-tour 2012/09/29 10:28:46 Open your web browser and visit http://127.0.0.1:3999/
Success! You have a working Go installation!