英文:
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
,如果你打算将其作为解决方案,它可能会导致可执行文件损坏。
英文:
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.
答案1
得分: 13
使用-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
.
.
在Go社区中,使用strip
工具仍然存在一些争议,尽管据说已经修复了一些问题。有人说有时会出现未知和不可预测的错误。请阅读这里和这里获取示例。
英文:
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.
答案2
得分: 8
trimpath
是一种不错的方法,但存在问题,比如go issue 24976。
看起来,当多个
-trimpath
标志传递给go工具编译时,最后一个标志会生效。
的确,从我所了解的情况来看,
trimpath
标志被定义为普通的字符串标志,而不是列表。
但是通过CL 173344,这个问题现在已经修复(适用于即将发布的Go 1.13版本)。
cmd/internal/objabi: 扩展 -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所指出的。
英文:
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.
答案3
得分: -1
这是给那些不支持-trimpath构建选项的Go版本的人使用的...
我必须使用1.10.8版本。我的项目有多个包。从可执行文件中删除所有包(不仅仅是main包)的文件路径的技巧是使用包模式"all"和-gcflags:
go1.10.8 build -gcflags=all=-trimpath=%GOPATH%
英文:
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%
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论