author
Kevin Kelche

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.

skeleton
go build [-o output] [build flags] [packages]

Copied!

Examples

Let’s create a go programme called main.go with the following content:

main.go
package main

import "fmt"

func main() {
 for i := 0; i < 10; i++ {
    fmt.Printf("Go is awesome!\n")
  }
}

Copied!

Remember to run go mod init to create a go.mod file. Then run go build to compile the source code.

Terminal
go build -o awesome

Copied!

The -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.

Terminal
./awesome

Copied!

Build 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:

-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:

main.go
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()
    }
}

Copied!

To show the escape analysis output, run the following command:

Terminal
go build -gcflags="-m=2 -l" main.go

Copied!

The -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:

Terminal
# 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

Copied!

-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:

main.go
package main

import "fmt"

var version = "1.0.0"

func main() {
    fmt.Printf("Version: %s\n", version)
}

Copied!

To set the version of the program, run the following command:

Terminal
go build -ldflags "-X main.version=1.2.3" main.go

Copied!

By 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:

Terminal
Version: 1.2.3

Copied!

These 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.

Subscribe to my newsletter

Get the latest posts delivered right to your inbox.