通过ldflags选项传递给go命令时,w标志是什么意思?

Context:

go 1.2, ubuntu 12.10

Goal:

Reduce size of compiled binaries

Currently in my build process, I run "go install" to generate the binary. The I read from somewhere that if I pass in -w it will shrink the binary. I tried it by passing it into the -ldflags option & my binary lost 1MB in size.

  1. Is this -w flag documented anywhere? What does it actually do?
  2. I then discovered the strip -s <binary> command and ran that on top of -w and got another weight loss of 750KB ! The resulting binary runs fine. Does stripping cause problems in any situations ?

You will get the smallest binaries if you compile with -ldflags '-w -s'. The -w turns off DWARF debugging information: you will not be able to use gdb on the binary to look at specific functions or set breakpoints or get stack traces, because all the metadata gdb needs will not be included. You will also not be able to use other tools that depend on the information, like pprof profiling. The -s turns off generation of the Go symbol table: you will not be able to use 'go tool nm' to list the symbols in the binary. Strip -s is like passing -s to -ldflags but it doesn't strip quite as much. 'Go tool nm' might still work after 'strip -s'. I am not completely sure.

None of these - not -ldflags -w, not -ldflags -s, not strip -s - should affect the execution of the actual program. They only affect whether you can debug or analyze the program with other tools.

The go help build says that

-ldflags 'flag list'
    arguments to pass on each 5l, 6l, or 8l linker invocation. 

So, we can invoke go tool 6l to see all it's options. One of them is

-w  disable DWARF generation 

By the way, 5l stands for ARM ($GOARCH = arm), 6l stands for x86-64 ($GOARCH = amd64), and 8l is for x86 ($GOARCH = 386).

If you really want to view raw DWARF info you should use dwarfdump -a on OS X and objdump -wg on Linux. Warning! Output will be long, very long.

I'm afraid it might cause problems in programs compiled with Go 1.2's gc suite of tools—refer to this discussion.

The general idea is that while Go compiles down to machine code just like C, it's more higher-level than C. For instance, it has built-in detailed panic() stack traces which depend on debug info. The sizes of the gc-generated binaries could indeed have been smaller, and it might be addresseed while cooking Go 1.3, but really the size of a compiled program in most today's environments is not a big deal to be too concerned about.

You can get help from go tool link

$ go tool link
  ...
  -s    disable symbol table
  -w    disable DWARF generation