Getting started with Go
By: Uday Hiwarale
Tags: Golang Tutorial, Go Programming Language, Programming, Golang, Go Programming

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. You can check the Go version using go version command. Go supports a much better way to manage your project using Go Modules. Follow this article to know more. Go workspaces ( GOPATH ) will be deprecated soon⁰.

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, as long as you keep GOPATH environment variable pointed to the current working workspace directory whenever you are working on the given project.

Similar to $GOROOT , $GOPATH by default points to $HOME/go directory in UNIX and %USERPROFILE%\go on windows. Hence, it is not absolutely necessary to setup GOPATH environment variable.

Workspace directory structure

A Go workspace directory must have three sub-directories viz. src , pkg and bin . If you want to set up Go workspace, follow this documentation. If you are using macOS, then you can follow this Medium article to setup environment variables both temporarily or permanently.

↪ 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. Hence, 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.

Therefore 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 compiles the 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.

(go build command)

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. Learn more about go build vs go install commands from here.