Installing Go on your system, setting up environment variables, understanding root / workspace directories.

Installation

A language typically consists of the language specifications (syntax), standard library, a runtime environment, and a compiler. When you install Go, these are all the things you will get.

As Go is an open-source and free programming language, you can install it from the source. It also provides compiled binaries to install Go on your system with ease.

It comes with Windows and macOS installer packages which I would recommend if you are using Windows or macOS. All other download and installation related information are available at golang.org.

Go Installation Directory

When you install Go on your system, it creates a directory /usr/local/go in UNIX or c:/go in Windows. Then it copies all necessary code and binaries needed for Go to function in this directory.

This is where Go’s command-line tools, standard library and compiler lives. Whenever you import a package from Go’s standard library, Go looks for the package in this directory.

Custom Installation directory

If your Go installation directory is different than what Go assumes where it would be, you can use GOROOT environment variable. Edit your ~/.bash_profile and add:

export GOROOT=/usr/local/custom-go

Go Workspace

If you are working on Go v1.11+, then you do not need to set up a workspace directory using GOPATH environment variable. Go supports a much better way to manage your project using Go Modules.

You can create a Go program anywhere you want on your system. A typical Go program is a plain text file with .go file extension. You can run this program using go run hello.go command where hello.go is a Go program file in the current directory.

A workspace is Go’s way to facilitate project management. A workspace, in a nutshell, is a directory on your system where Go looks for source code files, manages dependency packages and build distribution binary files.

Whenever a Go program encounters an import statement, it looks for the package in the Go’s standard library ($GOROOT/src). If the package is not available there, then Go refers to the system's environment variable GOPATH which is the path to Go workspace directory and looks for packages in $GOPATH/src directory.

You can have as many workspaces as you want!

Workspace directory structure

A Go workspace directory must have three sub-directories viz. src, pkg and bin.

src

The src directory contains Go packages. A package in nutshell is a project directory containing Go source code (.go files). Any packages installed using go get command will reside here as well (and its dependency packages).

In Go, every program is contained in a package. Whenever you will be working with a new Go project, you need to create a new directory inside $GOPATH/src and work your way up from there.

pkg

The pkg directory contains Go package objects. They are the compiled versions of the original package source code and they have .a file extension (a stands for archived).

These files contain the compiled package binary code, along with debugging symbols and source information. A package object is customized for machine architecture and the Go version. These files are created by the Go pack tool while building/installing a package.

Whenever you install a 3rd party package, a package object package-name.a is created for that package in this directory.

In Go, you typically use import "<package-name>" or import "<main/child-package>" syntax to import a package (like ES6 syntax). Normally, Go looks for these packages in $GOROOT/src or $GOPATH/src directories. But if it finds a precompiled package object associated with an imported package, then Go uses that instead.

Package objects are compiled and archived files for specific platforms. Hence you will see the platform architecture directory inside the pkg directory.

The advantage of having a package object is to save compilation time. As a package is nothing but a collection of Go programs, it has to go through Go compiler every single time the main program (a program who imports it) compiles. If a package has a compiled object file in the pkg directory for current system architecture, then it doesn’t get compiled again.

When you are referencing foo/bar package. It refers to $GOPATH/pkg/{arch}/foo/bar.a and not $GOPATH/src/foo/bar/*.go (for Go’s standard library package, it will be $GOROOT instead of $GOPATH).

A package object is created when you use go install command on non-main packages. You will learn about main and non-main packages in packages lesson. Package object are also called as cached objects or cached packages.

bin

A Go program can either meant to be used as utility inside a package or to perform some operation. We have seen packages and where they reside.

A Go program that is meant to perform some operation like make a network request or write something to a file needs to be compiled first so that your machine can understand the instructions. When you run go run hello.go command, Go compiler first compiled hello.go file and then executes the resultant binary code.

You can output a binary file from a Go program or package using go build <package-name> (main package) or go build program/path.go command. This will create a binary file in the current directory.

The bin directory contains the same binary executable files. These files are created by go install commands. go install command runs go build command internally and then outputs these files to the bin directory.

Generally, this directory is in the executable path of the system. Hence all the programs inside this directory are executable from the terminal.

go install command also creates package objects of any imported packages inside currently compiling Go program.
GOBIN is another environment variable that Go uses to put binary files created using go install command. By default, GOBIN is $GOPATH/bin but you can change it to whatever directory you like.

1. Set up environment variables

export GOPATH=/Users/your-user/go_workspaces/main
export GOBIN=$GOPATH/binPATH=$PATH:$GOPATH:$GOBIN
export PATH

Setting GOBIN environment variable is not necessary, but since bin directory of a workspace will be in our PATH, it’s a good idea to set it for simplicity.

2. Make sure, $GOPATH and $GOBIN is set

As discussed, there is no need to set GOROOT environment variables as we are using the default installation directory (on macOS = /usr/local/go).

3. Installing 3rd party package

This command will pull source code from the GitHub repository and clone it inside $GOPATH/src. This will also download other dependency packages of gorm and install them under src directory.

After package and dependencies are downloaded, Go will compile the package and create a single package object file in $GOPATH/pkg directory under the same directory structure of the package.

4. Create binaries

It doesn’t matter where you execute go install shape command, Go knows where shape package is from your defined GOPATH environment variable.

Using this command, a binary file is generated inside bin directory with the name of the package. Since this bin directory is in our PATH, we can execute this binary file just by its filename as the command.

I will continue to collect informations about the language Go and also serve some basic application examples written in Go. Will be published here and on GitHub.