So this weekend I decided to give the Go programming language (golang) a spin. Go is best described like this:
Go, also called golang, is a programming language initially developed at Google in 2007 by Robert Griesemer, Rob Pike, and Ken Thompson. It is a statically-typed language with syntax loosely derived from that of C, adding garbage collection, type safety, some dynamic-typing capabilities, additional built-in types such as variable-length arrays and key-value maps, and a large standard library. – Wikipedia
When you are stuck, don’t search the web for “Go”; it will not give relevant results. Use the word “golang” instead.
Installing golang on Ubuntu 14.04
I am using Ubuntu 14.04 (actually Xubuntu), but these instructions should also work on any other recent Debian-based Linux (like Mint 17). I tested using a clean install, so you should not run into unexpected dependencies. First we install the two prerequisites (Git and Mercurial):
sudo apt-get install mercurial git
Then we download the latest version of the Go language in which debugging is working: version 1.2.2. Debugging (gdb) is broken in golang 1.3 and hopefully gets fixed in 1.4. EDIT: Thank you ondrej for finding this issue. The following commands will download the software package and unpack it to the “go” directory in your home folder (in my case “/home/maurits/go”):
cd ~ wget http://golang.org/dl/go1.2.2.linux-amd64.tar.gz tar -xf go1.2.2.linux-amd64.tar.gz rm go1.2.2.linux-amd64.tar.gz
Go supports installing third party packages using the “go get” command. These are not installed in the same directory as the initial Go installation. This simplifies package management, because every project can have it’s own workspace if needed. So, we create a (first) workspace directory that will hold third party packages. We will name it “workspace-go” since it is still generic and it will be located in my home folder.
We will use the directory later, when we “go get” some third party packages.
Setting up the command-line environment
To avoid adding the GO settings to my environment, I have made a file that holds my Go environment variables. You need to set three variables: GOROOT is the installation directory of GO, GOPATH is the workspace directory for “go get” and finally it can be convenient to add the “bin” directories from GOROOT and GOPATH to the (search) PATH. Using the following commands I make a “go.env” file that can be used to set the environment variables.
echo "export GOROOT=\$HOME/go" > ~/go.env echo "export GOPATH=\$HOME/workspace-go" >> ~/go.env echo "export PATH=\$PATH:\$GOROOT/bin:\$GOPATH/bin" >> ~/go.env
To actually load the above file you have to type the following command in the Terminal:
Note that the environment variables are only set in the active terminal. When you open another Terminal you will have to run the “go.env” file before you can use the “go” command(s). When your Go environment is correctly set you can (for example) get some nice third party tools using:
go get code.google.com/p/go.tools/cmd/... go get github.com/golang/lint/golint
Run a for loop example from the command-line
There is a very good website named “Go by Example“. It holds a large set of small Go files that clearly show how the various built-in functions of the Go language work. I chose the “for loop” example to show how compiling and running a golang file works. I make a directory “hello” (from “hello world”) to store my first Go programs in. Then I download the “for.go” example:
mkdir ~/hello cd ~/hello wget https://raw.githubusercontent.com/mmcgrana/gobyexample/master/examples/for/for.go
To run the code you need to open a Terminal and load the Go environment from the “go.env” file. Now the “go” command is available and you can execute “go run” as shown below:
. ~/go.env cd ~/hello go run for.go
You can also first “build” an executable file. The advantage is that you can distribute this file. It can be executed on any other Linux machine with the same architecture. Go also support cross-compiling for other architectures. It means that Go does not require anything (a VM or run-time) to be installed on the target machine. The downside to this is that the executable size is large. This simple “for.go” script has a compiled size of 2,2 MB (megabyte). This can be reduced to 1,2 MB by removing debug symbols using the “ldflags” like below:
. ~/go.env cd ~/hello go build -ldflags "-s" for.go ./for
Debug from the command-line
Golang has decent GDB support. This may help you a lot when you run bugs that you cannot effectively squash using “printf debugging”. Below I give an example of a run where I break on line 19 of the “for.go” script. Note that you expect the variables “i” and “j” to be “4” and “7”. They will not have these values, unless you disable compiler optimizations by adding the “gcflags” to the build command as shown below:
. ~/go.env cd ~/hello go build -gcflags "-N -l" for.go gdb for b for.go:19 r l i loc q y
LiteIDE: a Go IDE with debugging capabilities
In the above section we have seen how to run, build and debug from the command line. Fortunately, there is also a nice IDE available that simplifies these things. It is called LiteIDE and it supports just one language: Go. The following commands download it from sourceforge and install it in the “liteide” directory in your home folder (in my case “/home/maurits/liteide”):
wget --content-disposition http://sourceforge.net/projects/liteide/files/X22/liteidex22.linux-64.tar.bz2/download tar -xf liteidex22.linux-64.tar.bz2 rm liteidex22.linux-64.tar.bz2
In the menu you can create a launcher that executes the following:
The following file can be used as an icon:
When you have started the application there is one thing you must do:
View -> Manage GOPATH... -> Add Directory... -> Select: ~/workspace-go
This will make sure that any third party package that you install can be loaded.
Step-by-step debugger for Go
To make sure the (GDB based) step-by-step debugger works you need to do the following:
Build -> Build Configuration... -> Custom -> BUILDARGS -> Enter: -gcflags "-N -l"
Verify everything is working correctly by executing the following debug run:
File -> Open Folder -> Click: hello -> Choose Double click "for.go" in the "Folders" pane Build -> Build (Ctrl-B) Put cursor on line 19 F9 (toggle breakpoint) F5 (start debugging) F5 (until green arrow is on line 19) Debug pane should show "Variables" tab with "i=4" and "j=7"