Compiling a Go Program
Tags: go
Published: 2022-03-07 21:38:22

The Go command provides a number of options allowing you to [run](https://pkg.go.dev/cmd/go#:~:text=go%20run%20%5Bbuild%20flags%5D%20%5B%2Dexec%20xprog%5D%20package%20%5Barguments...%5D), [build ](https://pkg.go.dev/cmd/go#:~:text=go%20build%20%5B%2Do%20output%5D%20%5Bbuild%20flags%5D%20%5Bpackages%5D) or [install](https://pkg.go.dev/cmd/go#:~:text=go%20install%20%5Bbuild%20flags%5D%20%5Bpackages%5D) your Go program. The following diagram illustrates these options at a high-level. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fgi4vsahb6kcv3dt0ttt.png)

# Running a Go Program
Go is a compiled language. Source code belonging to a Go project must be run through a compiler. The compiler generates a binary which can then be used to run the program on a target OS. 

## Phases of the compiler
- Scanner: Converts source code to tokens for use by the parser.
- Parser: Converts tokens into an abstract syntax tree to be used by code generation
- Code generation: Compiles and install the packages to `$GOPATH/bin`

## Options for Compile and Run

| Module  | Description |
| ---| ----|
| `go run`| A command used for convenience allowing you to compile and run a program. While it does generate a temporary binary to run the program, that binary is deleted once execution completes.|
| `go build`| A command which compiles the packages named by the import paths, along with their dependencies, into a binary in the current working directory. It does not install the resulting binary.  |
| `go install`| A command which compiles the command in a temporary directory and moves the generated binary to the default target `$GOPATH/bin` alongside third-party dependencies. If a value has been provided for the $GOBIN environment variable, then it will install to that location instead. 
 |

## Related Environment Variables

| Name| Description |
| ---| ----|
|`GOBIN`|If the `GOBIN` environment variable is set, commands are installed to the directory it names instead of the default `$GOPATH/bin` folder |
|`GOPATH`| Required to resolve import statements. Defaults to the user's home director, `$HOME/go` on Unix or `%USERPROFILE%/go` on Windows |

## The `GOPATH` directory structure
`GOPATH` is a list of directory trees containing source code.  It is consulted to resolve imports that cannot be found in the standard Go tree. 

- src - Holds source code. The path below `src ` indicates the import path. 
- pkg - Package directory holds installed package objects. Each target OS and architecture pair has its own subdirectory
- bin - Holds compiled commands. Each command is named from its source directory, but only the final element and not the entire path. The command prefix is stripped, so you can add `$GOPATH/bin` to your path to get all installed commands. 

## Useful Commands

| Name| Description |
| ---| ----|
| `go clean -cache`|Removes entire go build cache. |
| `go clean --modcache`|Removes entire module download cache. Including unpacked source code of versioned dependencies |
| `go tool fix`| Runs the `go fix` command on packages named by the import paths|
| `go mod vendor`|Copies all third party dependencies to vendor directory in your project root. The go command loads packages from vendor directory instead of downloading modules from their sources into the module cache |
|`go env`|Location of cached files from `go build`command|
| `go mod tidy`|Loads packages in main module and transitive dependencies recursively. Does not consider packages in the main module in directories named `testdata `or with names that start with '.' or '_' unless those packages are explicitly imported by other packages.  |

# References
[A Quick Guide to Go's Assembler](https://go.dev/doc/asm)