GoLang Modules & Binaries: Go Get vs Go Install
A simple example of Go modules and binaries
Introduction
Go uses modules as a way to package code and manage dependencies. It can be quite confusing when first starting the language to understand exactly how Go binaries and modules are installed and handled, and this short guide attempts to explain it with a few simple examples.
First, the basics:
GOPATH - This environment variable (use 'go env' to list all) is the path to the location that installed Go modules sit
GOROOT - This environment variable is the installation path of your Go installation, and holds your Go binary plus any default packages such as fmt
GOBIN - This is generally not set and defaults to $GOPATH/bin, and stores binaries that get installed via go install
So what is the difference between 'go get' and 'go install'? The documentation is not very clear and it certainly takes some digging.
'go get' is for installing modules. You will notice this when you try to import a module that is not installed and do 'go run main.go', it will prompt you to install the dependency via 'go get'.
'go install' is for installing binaries, not packages.
It's important to remember that go libraries are added via 'go get' to a project and are tracked in the the go.mod file. Go binaries are for use external to go development. Any user without go installed can run your binary. You could even 'go install' a binary, completely uninstall go, and still run the binary. 'go install' is essentially just 'go build' with the added fact that it places the executable in your $GOPATH/bin directory.
Demo
Now let's build it ourselves. We will be creating 2 projects:
go-module
go-binary
The idea is to install our module for use in the binary, then install the binary and see what happens.
go-module:
Create a new folder titled 'go-module'
Run 'go mod init github.com/[username]/go-module'
Add the file hello.go with the following contents:
package hello import ( "fmt" "github.com/pkg/errors" ) func Hello() { fmt.Println(errors.New("Testing Module!")) }
Save the file, upload to a git repository
Run 'go get github.com/pkg/errors'
- Notice this will install the errors package in your $GOPATH directory under $GOPATH/pkg/mod/github.com/pkg/errors. This is an example of installing a module
go-binary
Create a new folder titled
go-binary
Run
go mod init github.com/[username]/go-binary
Add the file main.go with the following contents:
package main import ( "fmt" module "github.com/[username]/go-module" ) func main() { fmt.Println("tesT") module.Hello() }
Save the file, upload to a git repository titled github.com/[username]/go-binary
Run
go get github.com/[username]/go-module
- You have just imported your first custom module
Now how to do we install this binary? First, a neat little command is go list -f '{{.Target}}'
, which will show you the install path of the executable one you install it. You can run this from your go-binary folder.
Now from a completely different terminal, run go install github.com/[username]/go-module
. Notice how this build places the source code in your $GOPATH/pkg directory while also placing the executable in your $GOPATH/bin directory.
This is a simple tutorial for using go get and go install, which both can be a bit confusing for first time go users.