我想从/Users/myuser/dev/go/src/fooapi/spikes/mongoapi.go
创建的可执行文件中删除所有路径信息,如go build
。
我正在编译这样的代码:
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
将从精灵二进制文件中删除任何路径信息。
$ 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和here的例子。
trimpath
是一个很好的方法,但有像go issue 24976这样的问题
看来,当多个
-trimpath
标志传递给工具编译时,最后一个获胜确实;从我所知道的
trimpath
标志被定义为普通的字符串标志,而不是列表。
但是使用CL 173344,现在已经修复了(即将推出的Go 1.13)
cmd / internal / objabi:expand -trimpath语法
此CL影响
-trimpath
和cmd/asm
提供的低级别cmd/compile
标志。以前,该标志采用了一个目录的名称,该目录将从生成的目标文件中的记录路径中进行修剪。
此CL使标志采用以分号分隔的路径列表。
此外,每个路径现在可以以可选的“
=>replacement
”结束,以指定替换该前导路径前缀的内容,而不是仅删除它。后续CL将向
cmd/go
添加一个模式,该模式使用这个更丰富的-trimpath
来构建不包含任何本地路径名的二进制文件。
这是CL 173345:
cmd/go
:添加-trimpath
构建标志“
go build -trimpath
”修剪生成的包和可执行文件中记录的文件路径,以避免记录任何本地目录的名称。 相反,文件似乎存储在名为“go/src/...
”(对于标准库)的目录中,或者以文件出现的模块或包命名。
这修正了issue 16860,这是关于Go能够生成逐位相同的二进制文件,如Ivan Daniluk所述。