Compiler and linker flags

While building a Go binary, the -gcflags flag lets you pass optional compiler arguments, while the -ldflags flag lets you pass optional linker arguments. A full list of compiler and linker flags can be found by invoking the following commands:

go tool compile -help
go tool link -help

Let's look at an example of utilizing compiler and linker flags. We can build a simple program that returns the value of an uninitialized string variable. The following program seems innocuous enough:

package main
import "fmt"

var linkerFlag string
func main() {
fmt.Println(linkerFlag)
}

If we build this with some of the common compiler and linker flags, we will see some helpful output:

The compiler flags that we passed here achieve the following:

  • "-m -m": Prints information about the compiler's optimization decisions. This is the output that we can see in the preceding screenshot after the build command.
  • "-N": Disables optimizations within the Go binary.
  • "-l": Disables inlining.

The linker flags that we passed do the following:

  • "-X main.linkerFlag=Hi_Gophers": Sets a value for the linkerFlag variable in main. Being able to add a variable during build time is important as many developers want to add some sort of build parameter to their code during compilation time. We can pass a build date using `date -u +.%Y%m%d%.H%M%S` or a git commit version using git rev-list -1 HEAD. These values can be helpful later for referencing the state of the build.
  • "-s": Disables the symbol table, a data structure that stores each identifier in the source code alongside declaration information. This is often not needed for production binaries.
  • "-w": Disables DWARF generation. The dwarf table often doesn't need to be saved since the Go binary includes basic type information, PC-to-line data, and a symbol table.

If we build the binary using a standard method followed by using some of the compiler and linker flags we have available, we will be able to see a difference in binary size:

  • Non-optimized build:
$ go build -ldflags "-X main.linkerFlag=Hi_Gophers" -o nonOptimized
  • Optimized build:
$ go build -gcflags="-N -l" -ldflags "-X main.linkerFlag=Hi_Gophers -s -w" -o Optimized

As we can see, the Optimized binary is 28.78% smaller than the nonOptimized binary:

Both of these binaries will perform the same function for the end user, so consider removing some of the build optimizations using compiler and linker flags in order to reduce the end resulting binary size. This can be beneficial during the storage and deployment of said binaries.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.23.147