当您创建共享对象时,您需要为其指定一个实际名称和一个SONAME
(共享对象名称)。这些用于安装共享对象(它会同时创建对象和各种链接)。
因此,您可能会遇到以下情况:
pax> ls -al xyz*
lrwxrwxrwx 1 pax pax 0 Nov 18 2009 xyz.so -> xyz.so.1
lrwxrwxrwx 1 pax pax 0 Nov 18 2009 xyz.so.1 -> xyz.so.1.5
-rw-r--r-- 1 pax pax 12345 Nov 18 2009 xyz.so.1.5
具有 xyz.so.1.5
的 SONAME
为 xyz.so.1
。
当链接器与 xyz.so
进行链接时,它会一直跟随文件链接到 xyz.so.1.5
并使用其 SONAME
为 xyz.so.1
存储在生成的可执行文件中,以便在运行时进行绑定。
然后,当您运行可执行文件时,它尝试使用存储在可执行文件中的 SONAME
,即 xyz.so.1
,这将指向特定的 xyz.so.1.N
(目前为 1.5,但可能会在以后更改为 1.6 .. 1.N)。
因此,您可以安装 xyz.so.1.6
并更新 xyz.so.1
链接以指向它,已链接的可执行文件将使用它(在运行时)。
这种多层方法的优点在于,您可以拥有同名的多个潜在不兼容库(
xyz.so.1.*
,
xyz.so.2.*
),但是在每个主要版本中,您可以自由升级它们,因为它们应该是兼容的。
当您链接以创建新的可执行文件时:
- 那些链接到
xyz.so
的将获得最新主版本的最新次要版本。
- 其他链接到
xyz.so.1
的将获得特定主版本的最新次要版本。
- 仍然其他链接到
xyz.so.1.2
的将获得特定主版本的特定次要版本。
现在请记住上面那段话,我们来看看您的评论:
假设我编译了另一个版本的相同库,并使用以下实际名称:
libmy.so.2.0
。按照指南,
SONAME
将是
libmy.so.2.0
。
不,我不这样认为。更有可能是
libmy.so.2
的
SONAME
,这样你就可以对
2.x
流进行小的更新并获得最新的行为。
readelf -Wa /usr/lib/libstdc++.so.6 | grep SONAME
来检查系统上预安装库的 sonames,并看看指南如何得到贯彻实施。 - P Shved