我在我的二进制文件中看到了这一行:
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
我不应该摆脱它吗?实际上更令人困惑的是,为什么它首先存在,我觉得 gcc 默认编译仅在主机上运行的东西有点疯狂。仅仅依赖一些随机的 libc 可能会或可能不会在我最终将复制粘贴此二进制文件的机器上,这不是非常危险吗?我不明白。在 Windows 上,我想我会得到某种“缺少运行时”错误,该错误被版本化为我编译它的确切运行时,所以如果我在 XP 上使用某个编译器编译,那么任何主机也必须安装该运行时. 但是在 Linux 上我从来没有听说过这样的情况,或者在某个地方是否有一个包含 50 个不同 libc.so 的目录,并且当我的应用程序尝试启动时,正确的目录会被链接?因为我有种感觉。
至少对于 GNU C 库,链接会携带所使用的每个符号(函数等)的版本信息。你可以用
objdump -T
; 例如,在 上/bin/ls
,我得到等等
C 库开发人员竭尽全力确保 C 库保持向后兼容。上面的输出意味着
ls
需要__ctype_toupper_loc
2.3 或更高版本的 C 库等。任何提供所有必需符号的 C 库都可以运行给定的二进制文件;任何给定版本的 GNU C 库都提供了旧版本 C 库(可追溯到 1997 年)提供的所有符号的实现。基于 Linux 的系统(实际上是基于 ELF 的系统和其他系统)上的大多数库使用的另一种处理方式是 soname。每个库不仅定义了它的名称,还定义了一个版本号,只要引入了重大更改(在某些情况下,更频繁),它就会更改。可以并行安装具有不同 soname 的多个版本的库;例如
(这也被 C 库使用,如依赖项名称所证明的那样,
libc.so.6
但最后一次 GNU C 库 soname 碰撞发生在多年前。)为了解决您标题中的问题,可以静态链接 C 库,但它很少需要或有用(并且可能会令人困惑,因为即使 C 库是静态链接的,C 库的某些部分也是动态链接的)。静态链接其他库会很有用。其他语言使用不同的方法,例如 Go 程序是静态链接的。