这是 go 中的Hello world:
package main
import (
"fmt"
)
func main() {
fmt.Println("Go is great!")
}
将其放入hello.go
并编译:
go build -o hello_go_build hello.go
go build -o hello_go_build_gccgo --compiler gccgo hello.go
gccgo -o hello_gccgo_shared hello.go
gccgo -static -o hello_gccgo_static hello.go
首先,我注意到 hello_go_build_gccgo
和 hello_gccgo_shared
的大小不同。我在互联网上查找资料没有成功。有谁知道这是为什么?甚至更好,有人能告诉我如何解决这个问题吗?我尝试使用 -work
标志保留临时文件,但我找不到相关信息。
然后,您可能会注意到,两个静态链接的二进制文件的大小也不相同。实际上,使用 go build
(hello_go_build
) 命令编译的那个不仅适用于我的系统,而且适用于具有其他 Linux 发行版的其他系统,而 hello_go_build_gccgo
在我的系统和其他系统上失败并出现以下错误:
panic: runtime error: invalid memory address or nil pointer dereference
这是一个待解决的错误:https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/y2RIy0XLJ24
最后,即使现在,大小不再重要,我很好奇:go 编译器是否有任何选项可以进行函数级链接(而不是静态链接整个包,只链接所需的函数及其依赖项)?
最佳答案
First, I noticed hello_go_build_gccgo and hello_gccgo_shared are not of the same size. I looked for information on the Internet without success. Does anyone know why is that?
如果它们大小相同,我会觉得很奇怪。一个是静态链接,另一个使用共享库,那么为什么它们应该具有相同的大小?
Then, as you might notice, the two statically linked binaries does not have the same size either.
如果它们大小相同,我会觉得很奇怪。一个由 gc
编译,另一个由 gccgo
编译——两个完全不同的编译器。为什么应该期望它们生成相同大小的二进制文件?
Finally, even if nowadays, size does not matter anymore, I am curious: is there any option with anyone of the go compilers to do function level linking (instead of statically link a package as a whole, only link the functions needed and their dependencies)?
gc
没有“静态链接整个包”这样的东西。二进制文件中不存在未使用的函数(可能不仅是函数)。而且,IIRC,从第一天开始就是这种情况(从公开发布开始计算)。不确定前面是否也适用于 gccgo
,但我希望它在这方面也能做得很好。
关于compilation - 使用 gc 和 gccgo 编译的静态链接二进制文件的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14684830/