19

I want to remove all path information like /Users/myuser/dev/go/src/fooapi/spikes/mongoapi.go from the executable that I created with go build.

I'm compiling the code like this:

CGO_ENABLED=0 go build -v -a -ldflags="-w -s" -o ./fooapi spikes/mongoapi.go

Some part of the example assembly from the go build command above:

$ go tool objdump ./fooapi
.
.
TEXT main.init(SB) /Users/myuser/dev/go/src/api/spikes/mongoapi.go
mongoapi.go:60  0x12768c0   65488b0c25a0080000  GS MOVQ GS:0x8a0, CX
mongoapi.go:60  0x12768c9   483b6110        CMPQ 0x10(CX), SP
mongoapi.go:60  0x12768cd   7663            JBE 0x1276932
.
.

Note that: strip is not recommended and can lead to broken executables if you're going to recommend it as a solution.

Inanc Gumus
  • 25,195
  • 9
  • 85
  • 101
  • 7
    BTW, that issue about strip is very old, and no longer relevant. The generally accepted solution for _any_ toolchain is to build the executable in a temporary or generic build path. – JimB Jul 24 '17 at 13:44

3 Answers3

13

Use -trimpath flags to remove path information:

CGO_ENABLED=0 go build -v -a -ldflags="-w -s" \
    -gcflags=-trimpath=/Users/myuser/dev/go/src \
    -asmflags=-trimpath=/Users/myuser/dev/go/src \
    -o ./fooapi spikes/mongoapi.go

More Information:

Passing -trimpath to -gcflags and -asmflags will remove any path information from the elf binary.

$ go tool asm -help 2>&1 | grep -A1 trimpath
-trimpath string
    remove prefix from recorded source file paths

$ go tool compile -help|grep -A1 trimpath
-trimpath string
    remove prefix from recorded source file paths

You can check the result with go tool objdump:

$ go tool objdump ./fooapi
.
.
TEXT main.init(SB) api/spikes/mongoapi.go
mongoapi.go:60  0x12768c0   65488b0c25a0080000  GS MOVQ GS:0x8a0, CX
mongoapi.go:60  0x12768c9   483b6110        CMPQ 0x10(CX), SP
mongoapi.go:60  0x12768cd   7663            JBE 0x1276932
.
.

Using strip tool has still some controversies in go community, although it's been said that it's been fixed. Some say that unknown and unpredictable bugs occur sometimes. Read here and here for examples.

Inanc Gumus
  • 25,195
  • 9
  • 85
  • 101
  • 1
    I have been informed by Russ Cox that `-gcflags=-trimpath=...` and `-asmflags=-trimpath=...` are not officially supported and in fact they fail to fully remove the path from the binary. The correct parameter is just `-trimpath=...`. – AndreKR Oct 05 '22 at 20:57
8

trimpath is a good approach, but had issues like go issue 24976

It appears that, when multiple -trimpath flags are passed to go tool compile, the last one wins

Indeed; from what I can tell the trimpath flag is defined as an ordinary string flag, not a list.

But with CL 173344, this is now fixed (for the upcoming Go 1.13)

cmd/internal/objabi: expand -trimpath syntax

This CL affects the low-level -trimpath flag provided by both cmd/asm and cmd/compile.

Previously, the flag took the name of a single directory that would be trimmed from recorded paths in the resulting object file.

This CL makes the flag take a semicolon-separated list of paths.

Further, each path can now end in an optional "=>replacement" to specify what to replace that leading path prefix with, instead of only dropping it.

A followup CL will add a mode to cmd/go that uses this richer -trimpath to build binaries that do not contain any local path names.

This is CL 173345:

cmd/go: add -trimpath build flag

"go build -trimpath" trims the recorded file paths in the resulting packages and executables to avoid recording the names of any local directories.
Instead, the files appear to be stored in directories named either "go/src/..." (for the standard library) or named after the module or package in which the files appear.

This fixes issue 16860, which is about Go ability to generate bit-for-bit identical binaries, as noted by Ivan Daniluk.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
-1

This is for anyone using a version of go that does NOT support the -trimpath build option...

I have to use version 1.10.8. My project has multiple packages. The trick to removing the file path for ALL the packages (not just main) from the executable is to use the package pattern "all" with -gcflags:

go1.10.8 build -gcflags=all=-trimpath=%GOPATH%
Shonie
  • 1