![Linux so 约定:.so 链接是否来自开发包?](https://linux22.com/image/227935/Linux%20so%20%E7%BA%A6%E5%AE%9A%EF%BC%9A.so%20%E9%93%BE%E6%8E%A5%E6%98%AF%E5%90%A6%E6%9D%A5%E8%87%AA%E5%BC%80%E5%8F%91%E5%8C%85%EF%BC%9F.png)
在我的 Ubuntu jammy Linux PC 上,安装 libuv1 软件包 ( apt-get install libuv1
) 后,我注意到有一个名为 的文件libuv.so.1.0.0
和一个名为 的符号链接libuv.so.1
:
$ find /usr -name "libuv.so*" 2>/dev/null
/usr/lib/x86_64-linux-gnu/libuv.so.1.0.0
/usr/lib/x86_64-linux-gnu/libuv.so.1
$ ls -l /usr/lib/x86_64-linux-gnu/libuv.so*
lrwxrwxrwx 1 root root 14 Jan 15 2022 /usr/lib/x86_64-linux-gnu/libuv.so.1 -> libuv.so.1.0.0
-rw-r--r-- 1 root root 198744 Jan 15 2022 /usr/lib/x86_64-linux-gnu/libuv.so.1.0.0
$
从可能不完整的理解来看,我期望还有一个libuv.so
符号链接,例如/usr/lib/x86_64-linux-gnu/libuv.so -> libuv.so.1
.
我见过.so
符号链接存在/不存在的这种混合,但从未正确理解其背后是否有原因/约定。
我想我可能偶然发现了答案这篇博文。如果我正确理解了该帖子的内容:
- 语义版本的 .so 文件,例如
libfoo.so.1.0.0
符号链接最终解析的真实文件;它们是用soname
选项编译的,例如gcc -I . foo.c -shared -Wl,-soname=libfoo.so.1 -o libfoo.so.1.0.0
。 - 由于使用了该
soname
选项,当使用 编译二进制文件时-lfoo
(在存在libfoo.so -> libfoo.so.1 -> libfoo.so.1.0.0
链接的环境中),编译器/链接器将查找libfoo.so
,它解析为libfoo.so.1.0.0
,已使用 进行编译-soname=libfoo.so.1
,因此二进制文件将知道它需要libfoo.so.1
在运行时。
(即readelf -d
在二进制文件上会输出类似的内容0x0000000000000001 (NEEDED) Shared library: [libfoo.so.1]
) libfoo.so.1 -> libfoo.so.1.0.0
当二进制文件在只有(即没有)的环境中运行时libfoo.so -> libfoo.so.1
,它将运行良好:由于上述原因,它将寻找libfoo.so.1
,而不是libfoo.so
。
我的猜想:这似乎意味着只有当你发展对于共享库,您将需要符号libfoo.so
链接,因为需要指定-l
标志,例如g++ use-foo.cpp -o ./use-foo -lfoo
.在这种情况下,使用-lfoo
意味着编译器/链接器将寻找libfoo.so
,而不是libfoo.so.*
。
上面的内容似乎证实了编译一个动态链接的简单 hello-world 示例,并检查了与软件包一起安装的libuv1
内容libuv1-dev
:
$ apt-file list libuv1 | grep so.*
libuv1: /usr/lib/x86_64-linux-gnu/libuv.so.1
libuv1: /usr/lib/x86_64-linux-gnu/libuv.so.1.0.0
$
$ apt-file list libuv1-dev | grep so.*
libuv1-dev: /usr/lib/x86_64-linux-gnu/libuv.so
$
但当我找到文件时,工作就被打乱了,不是符号链接,就像libmemusage.so
(我只是随机挑选一个例子):
$ ls -l /usr/lib/x86_64-linux-gnu/libmemusage.so
-rw-r--r-- 1 root root 18904 Sep 25 07:45 /usr/lib/x86_64-linux-gnu/libmemusage.so
我的问题是:libfoo.so
是否有一条全面的规则来描述、libfoo.so.x
、 和之间的关系libfoo.so.x.y.z
,何时以及为什么应存在它们的任何特定组合,以及何时以及为何其中任何一个应该是文件与符号链接?
作为一个非开发者 Linux PC 用户,是否有任何情况应该创建任何“缺失”的符号链接(如问题的开头,我看到了libuv.so.1
但没有libuv.so
)? (这个问题的背景:过去,我被要求创建一个“缺失”的libfoo.so
符号链接,当libfoo.so.x
和/或libfoo.so.x.y.z
存在时,但我从来没有正确理解为什么这是必要的,除了一个半生不熟的概念“总是存在”一堆.so
文件,而且他们似乎有“对应的”.so.x
和.so.x.y.z
文件)。
(我可以看到这个问题可能属于 Stack Overflow:它与编程无关,但我最终认为问题的核心是关于 Unix/Linux 约定。但是,如果确定这个问题是更适合 Stack Overflow。)