CGO_ENABLED 如何影响动态链接和静态链接?

Tho*_*mas 10 dynamic-linking go static-linking

我们正在编译要在 docker 上运行的 Go 代码,并且正在调查为什么我们的二进制文件没有执行。我们发现它缺少一些动态库(尽管我们想要静态链接的二进制文件)。

这就是它的编译方式。

env GOOS=linux CGO_ENABLED=1 GO111MODULE=on GOPRIVATE=github.com/ourrepo GOPROXY=https://proxy.golang.org go build --installsuffix cgo --ldflags='-extldflags=-static' -o program main.go

使用相同的构建命令CGO_ENABLED=0最终解决了问题,并且输出二进制文件是静态链接的。

现在奇怪的部分是我们有另一个程序使用相同的构建命令,这次是CGO_ENABLED=1and...它是静态链接的!

所以我很困惑为什么在某些情况下CGO_ENABLED=1会产生动态链接,有时会产生静态链接。很高兴提供更多细节。

Opn*_*cus 10

一些 Go 包在底层使用 CGO,利用(非常)通用的 C 库来实现跨环境和运行时遇到的边缘情况的更广泛兼容性。

这些通用库可以在大多数主要操作系统发行版上找到 - 但显然不包含在 Scratch 映像中(本质上是完全空的)。

CGO_ENABLED默认情况下设置为 1,这意味着CGO_ENABLED=0即使使用该-static标志,也必须显式禁用它以避免它。

  • 值得注意的是,“net”包默认使用一些“libc”函数。 (4认同)
  • “减少编译后的二进制文件大小。” 并不真地。在 Cgo 下,二进制文件包含两个解析器。Pure-Go 是默认设置,并且始终使用,除非您明确告知它,或者操作系统配置具有 pure-Go 不支持的功能。Cgo 解析器对资源的消耗要大得多,因为每个 Cgo 调用都会消耗整个线程而不是 goroutine。它的存在可能是为了兼容性(pure-Go 尝试模拟常见的实现),并且因为在某些系统上您无法自己发送 DNS 请求 (macOS)。Go 不需要 libc。 (4认同)