我知道--ldflags="-s -w"
会使Go二进制文件的大小更小,但是如果不与没有do标志的二进制进行比较,我们如何知道使用ldflags="-s -w"
编译的Go二进制文件呢?
发布于 2017-05-24 13:40:28
免责声明:我不是编译工具链和可执行文件格式的专家。我尽量不要说蠢话,但如果你看到任何错误,请纠正我!
我在ArchLinux笔记本电脑上运行了这些测试,使用的是x86_64架构。Go版本为1.8.1。
首先,我们需要知道这些标志在哪里被实际使用:
$ go help build
...
-ldflags 'flag list'
arguments to pass on each go tool link invocation
...
显然,标志只是传递给go tool link
调用。看看帮助,我们有一些更多的信息:
$ go tool link
...
-s disable symbol table
...
-w disable DWARF generation
...
摘自对ELF的简短介绍,我发现了这里,这里是有关符号表的标题文本:
对象文件的符号表包含定位和重新定位程序的符号定义和引用所需的信息。
至于侏儒,这是一种调试数据的格式。
从那里,我们如何知道二进制是否有符号表,或侏儒启用?答案在于ELF部分。也许还有其他的方法,但这是我发现的,而且很容易检查。下面是我用来确定Golang二进制文件是用-ldflags='-s'
还是-ldflags='-w'
编译的规则
.symtab
。.debug_info
。本节并不是唯一在场的部分,而是作为一个指标。在Linux上,有一些工具可以读取节名来提取这些信息。readelf
和nm
就是例子,但可能更多。
另外,Go还提供了一个debug/elf
包,可以用来获取这些信息。下面是一个完成此工作的示例程序:
package main
import "fmt"
import "os"
import "debug/elf"
func main() {
fileName := "path/to/main"
fp, err := elf.Open(fileName)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
symtab := fp.Section(".symtab")
if symtab == nil {
fmt.Println("No Symbol Table : compiled with -ldflags='-s'")
}
debugInfo := fp.Section(".debug_info")
if debugInfo == nil {
fmt.Println("No DWARF data : compiled with -ldflags='-w'")
}
}
我在基本的Golang上测试了这个程序,没有使用标志,只使用-s
标志,只使用-w
标志和-s -w
标志。我注意到,在仅用-s
编译时,它也删除了矮小数据,但我没有搜索原因。除此之外,结果与预期的一样。
虽然ELF是焦点格式,但同样的方法可以应用于Windows可执行文件(在Golang中有一个debug/pe
包)。
https://stackoverflow.com/questions/44148449
复制