从 go 二进制文件中的 TEXT 指令中删除文件路径

Remove file paths from TEXT directives in go binaries

我想从我用 go build 创建的可执行文件中 删除 所有路径信息,例如 /Users/myuser/dev/go/src/fooapi/spikes/mongoapi.go

我正在这样编译代码:

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

来自上面 go build 命令的示例程序集的某些部分:

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

请注意:strip 不推荐,can lead to broken executables 如果您打算推荐它作为解决方案。

使用-trimpath 标志删除路径信息:

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

更多信息:

-trimpath 传递给 -gcflags-asmflags 将从 elf 二进制文件中删除所有路径信息。

$ 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

你可以用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
.
.

使用strip工具在go社区中仍有一些争议,虽然据说已经修复了。有人说有时会发生未知和不可预测的错误。阅读 here and here 示例。

trimpath 是一个很好的方法,但是有像 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.

但在 CL 173344 中,此问题现已修复(对于即将发布的 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.

这是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.

这修复了 issue 16860, which is about Go ability to generate bit-for-bit identical binaries, as noted by Ivan Daniluk