为什么CGO_启用=1默认值?

为什么CGO_启用=1默认值?,go,Go,CGO_ENABLED=1我认为是当前的默认值,这意味着它依赖于GLIBC,GLIBC可以在更新和发行版之间进行突破性的更改 CGO_ENABLED=0是创建静态独立二进制文件的变通方法,因此为什么这不是默认值?一般来说,CGO_ENABLED=1会导致更快、更小的构建和运行时间,因为它可以在构建操作系统上运行时动态加载主机操作系统的本机库(例如,glibc、DNS解析器等)。这是当地快速发展的理想选择。对于部署,CGO_ENABLED=1在考虑部署托管操作系统时可能不实用,甚至不可能 如果您纯

CGO_ENABLED=1我认为是当前的默认值,这意味着它依赖于GLIBC,GLIBC可以在更新和发行版之间进行突破性的更改


CGO_ENABLED=0是创建静态独立二进制文件的变通方法,因此为什么这不是默认值?

一般来说,
CGO_ENABLED=1
会导致更快、更小的构建和运行时间,因为它可以在构建操作系统上运行时动态加载主机操作系统的本机库(例如,
glibc
、DNS解析器等)。这是当地快速发展的理想选择。对于部署,
CGO_ENABLED=1
在考虑部署托管操作系统时可能不实用,甚至不可能

如果您纯粹使用标准库,则可能不需要启用CGO。在某些标准库中,如果使用纯Go版本(
CGO_ENABLED=1
)或CGO ENABLED版本,行为将有所不同:

  • :请参阅DNS
  • :
    • CGO_ENABLED=1
      使用本机操作系统(例如,在Linux上
      nsswitch
      )进行ID查找
    • CGO_ENABLED=0
      使用一个基本的Go实现(例如从
      /etc/passwd
      读取)-它不包括主机可能知道的其他ID注册表
部署

虽然
CGO_ENABLED=1
二进制文件可能更小,但它也依赖于提供主机操作系统。比较Docker图像:

  • ubuntu:20.04
    是73.9MB(
    glibc
    :GNU libc)
  • alpine:3.12.1
    为5.57MB(
    musl
    libc)
因此,添加操作系统(即使是最小的操作系统)也会增加额外的负担
alpine
的最小尺寸看起来很吸引人,但是它的
libc
可能与依赖
glibc
的软件包不兼容

然而,
CGO_ENABLED=0
非常适合docker映像部署,因为不需要捆绑主机操作系统


但是,如果您的应用程序导入了一个带有C代码的包(例如),那么您的构建必须启用CGO。

“是创建静态独立二进制文件的解决方法”——一般来说,这是不够的。有时您需要CGO,有时您不需要。我经常这样做。为什么默认值应该与我经常需要的不同?这个问题是高度基于意见的。基于意见?难道我不能期望Go二进制文件是静态的和可移植的吗?libc基本上是可移植的,需要它的用户将需要它。如果您在cgo中使用更具体的东西,那么您可能无论如何都无法禁用它。“难道我不能期望Go二进制文件是静态的和可移植的吗?”——您可以期望,没有可移植的方法可以做到这一点:“因为它动态加载主机操作系统的本机glibc”?你能详细说明一下吗?你怎么知道的?为什么?在哪个操作系统上?“一般来说,CGO_ENABLED=1会导致更快、更小的构建和运行时”,不,这不是libc链接的原因。不包括第三方软件包使用cgo进行某些操作时,std库会将其用于一些非常特定的用例,但大多数情况下,您使用的是glibc,您无论如何都不想静态链接。@JimbB我不确定我是否理解您的评论-您可以展开吗?我在std库中介绍了一些微妙的
CGO
与非
CGO
行为的例子。这里有多个合并的部分,它们都与“更快、更小的构建和运行时”无关。主机libc的默认用途是用于无法在std lib中复制的功能
CGO_ENABLED=1
是默认值,因为它是——不需要是,但已确定这将是最有用的默认值。它不会加速任何事情。在C库中链接要慢一些,因为您要做更多的工作来构建它。调用C库比较慢,因为切换堆栈需要一些时间。它与本地开发与部署无关,您可以使用任何您需要的工具。而且
CGO_ENABLED=1
不会使二进制文件变小,事实上它通常会使二进制文件变大一些,因为它必须在额外的代码中编译以处理CGO和CGO代码正在执行的任何其他操作。