为什么 libc 有两个版本号(Ubuntu)?

Why does libc have two version numbers (on Ubuntu)?

如果我 运行 这个在 Docker 的 ubuntu:latest:

root@4304dfbfa661:/# ls lib/x86_64-linux-gnu/libc* -l
-rwxr-xr-x 1 root root 1868984 Jan 15 02:51 lib/x86_64-linux-gnu/libc-2.23.so
lrwxrwxrwx 1 root root      12 Jan 15 02:51 lib/x86_64-linux-gnu/libc.so.6 -> libc-2.23.so

好像libc的编号是6和2-23。为什么会有两个版本号?

NB libc 是(特殊的)可执行文件并且 运行ning 它给出

root@4304dfbfa661:/# ./lib/x86_64-linux-gnu/libc.so.6
GNU C Library (Ubuntu GLIBC 2.23-0ubuntu10) stable release version 2.23, by Roland McGrath et al.

所以令人惊讶的是 libc.so.6libc [或者更准确地说,glibc] 是否有与版本号无关的名称?

编辑: 澄清一下,我理解符号链接。令我困惑的是两种编号方案的存在。如果你看例如libstdc++,你会发现

lrwxrwxrwx 1 root root     19 Sep 11  2017 ./usr/lib64/libstdc++.so.6 -> libstdc++.so.6.0.19
-rwxr-xr-x 1 root root 995840 Aug  1  2017 ./usr/lib64/libstdc++.so.6.0.19

foo.so.6 作为 foo.so.6.0.19 的符号链接是有道理的。将 foo.so.6 作为 foo-2.23.so 的符号链接令人困惑...

What confuses me is the existence of two numbering schemes.

在发明 GNU 符号版本控制之前,对 ABI 的任何更改 都需要 引入一个全新版本的库,并且必须有两个(或更多)副本出现在系统上。

描述了外部库版本控制,例如here.

随着每个符号版本控制(GNU 符号版本控制)的引入,外部库版本控制变得完全不必要:单个库可以支持多个 ABI。

这就是为什么 libc.so.6 一直停留在第 6 版(1990 年代后期)。根本没有理由使用符号链接——库可以简单地命名为 libc.so.6。但是,拥有符号链接并指向当前库版本是方便,例如libc-2.27.so.

libstdc++.so卡在libstdc++.so.6不同:维护多个C++ ABI难度要大得多。因此,库不断增加每个 GCC 版本的次要版本(较新的 GCC 需要较新版本的 libstdc++.so)。

但他们没有更改 .so.6 部分,因为这样做需要多个 libstdc++.so 副本(这将共享 99% 的代码)。

关于 two numbering schemes 的历史:

Linux libc 在 1980 年代从 FSF 的 glibc 分叉出来,并在 1997-98 年再次变回 glibc 以更正 'strategic mistake'.

然后:

The version numbers were a minor problem: The GNU/Linux guys had already reached 5.4.47, while FSF was just hitting 2.0. They probably pondered for about a millisecond asking Stallman to make his next version 6.0 for their benefit. Then they laughed, said "This is Stallman we're talking about, right?", and decided out-stubborning Richard was not a wise idea. So, the convention is that Linux libc version 6.0 is the same as glibc 2.0.

details here

因此,libc.so.6 只是一个转换名称。