Golang Build - A Complete Guide
Introduction
Golang comes with the go command, used to build, test, and install Go packages and modules. The go command is the primary tool for managing your Go source code. In this artilce we’ll explore the go build command in detail.
What is go build?
The go build command compiles Go source code into a binary executable. The go build also compiles the dependencies of that source code.
go build [-o output] [build flags] [packages]Examples
Let’s create a go programme called main.go with the following content:
package main
import "fmt"
func main() {
for i := 0; i < 10; i++ {
fmt.Printf("Go is awesome!\n")
}
}Remember to run go mod init to create a go.mod file. Then run go build to compile the source code.
go build -o awesomeThe -o flag is used to specify the name of the output file. In this case, the output file is called awesome. If you don’t specify the -o flag, the output file will be called main.
To run the output file, run ./awesome in the terminal if you’re on Linux or Mac. If you’re on Windows, run awesome.exe.
./awesomeBuild Flags
go build comes with many flags that can be used to modify the build process. Here are some of the most commonly used build flags:
-a- forces rebuilding of packages that are already up-to-date.-i- installs the dependencies to$GOPATH/pkginstead of the default temporary directory.-o- specifies the name of the output file.-p- specifies the number of programs, such as build commands or test binaries, that can be run in parallel.
-gcflags
The -gcflags flag is used to pass arguments to the Go compiler. The -gcflags flag is useful for debugging and performance tuning. For instace when exploring escape analysis, you can use the -gcflags flag to show the escape analysis output.
Here is an example of a program that uses the -gcflags flag to show the escape analysis output:
package main
import "fmt"
func main() {
s := make([]func(), 4)
for i := 0; i < 4; i++ {
i:=i
s[i] = func() {
fmt.Printf("%d @ %p \n", i, &i)
}
}
for _, f := range s {
f()
}
}To show the escape analysis output, run the following command:
go build -gcflags="-m=2 -l" main.goThe -m=2 flag tells the compiler to show the escape analysis output. The -l flag tells the compiler to disable inlining.
The output of the above command will be:
# command-line-arguments
./main.go:9:16: func literal escapes to heap:
./main.go:9:16: flow: {heap} = &{storage for func literal}:
./main.go:9:16: from func literal (spill) at ./main.go:9:16
./main.go:9:16: from s[i] = func literal (assign) at ./main.go:9:14
./main.go:8:2: main capturing by main: i (addr=true assign=false width=8)
./main.go:8:2: i escapes to heap:
./main.go:8:2: flow: {storage for func literal} = &i:
./main.go:8:2: from i (captured by a closure) at ./main.go:10:38
./main.go:8:2: from i (mainerence) at ./main.go:10:38
./main.go:10:24: i escapes to heap:
./main.go:10:24: flow: {storage for ... argument} = &{storage for i}:
./main.go:10:24: from i (spill) at ./main.go:10:24
./main.go:10:24: from ... argument (slice-literal-element) at ./main.go:10:23
./main.go:10:24: flow: {heap} = {storage for ... argument}:
./main.go:10:24: from ... argument (spill) at ./main.go:10:23
./main.go:10:24: from fmt.Printf("%d @ %p \n", ... argument...) (call parameter) at ./main.go:10:23
./main.go:8:2: moved to heap: i
./main.go:6:14: make([]func(), 4) does not escape
./main.go:9:16: func literal escapes to heap
./main.go:10:23: ... argument does not escape
./main.go:10:24: i escapes to heap-ldflags
The -ldflags flag is used to pass arguments to the linker.
Here is an example of a program that uses the -ldflags flag to set the version of the program:
package main
import "fmt"
var version = "1.0.0"
func main() {
fmt.Printf("Version: %s\n", version)
}To set the version of the program, run the following command:
go build -ldflags "-X main.version=1.2.3" main.goBy default, the version of the program will be 1.0.0. But, by using the -ldflags flag, we can set the version of the program to 1.2.3.
The output of the above command will be:
Version: 1.2.3These are but a few examples of flags that we have used with the go build command. For a full list of flags, run go help build.
Conclusion
In this article we explored the go build command in detail. We looked at some of thmmonly used build flags. We also looked at some examples of how to use the -gcflags and -ldflags flags.

