it-swarm.cn

SO(共享对象)数字)如何工作?

我知道Linux下的共享库使用“ so数字”,即共享库的不同版本具有不同的扩展名,例如:

  • example.so.1
  • example.so.2

我知道这个想法是要有两个不同的文件,以便在系统上可以存在一个库的两个版本(与Windows上的“ DLL Hell”相对)。我想知道这在实际中如何运作?通常,我看到example.so实际上是到example.so.2的符号链接,其中.2是最新版本。然后,取决于example.so较旧版本的应用程序如何正确识别它?关于必须使用什么数字有任何规定吗?还是这仅仅是约定?是否与Windows在系统之间转移软件二进制文件不同,如果系统具有共享对象的较新版本,则从源代码进行编译时会自动链接到较旧的版本吗?

我怀疑这与ldconfig有关,但不确定如何。

127
user119

二进制文件本身知道它们所依赖的共享库的版本,并特别要求它。您可以使用ldd来显示依赖关系。我的ls是:

$ ldd /bin/ls
    linux-gate.so.1 =>  (0xb784e000)
    librt.so.1 => /lib/librt.so.1 (0xb782c000)
    libacl.so.1 => /lib/libacl.so.1 (0xb7824000)
    libc.so.6 => /lib/libc.so.6 (0xb76dc000)
    libpthread.so.0 => /lib/libpthread.so.0 (0xb76c3000)
    /lib/ld-linux.so.2 (0xb784f000)
    libattr.so.1 => /lib/libattr.so.1 (0xb76bd000)

如您所见,它指向例如libpthread.so.0, 不只是 libpthread.so


符号链接的原因是链接器。当您想链接到libpthread.so直接,则给gcc标志-lpthread,并加上lib前缀和.so后缀自动。您不能告诉它添加.so.0后缀,因此符号链接指向lib的最新版本,以便于

91
Michael Mrozek

共享库中的数字是Linux中的惯例,用于标识库的API。通常,格式为:

libFOO.so.MAJOR.MINOR

正如您通常注意到的那样,从libFOO.so到libFOO.so.MAJOR.MINOR有一个符号链接。 ldconfig负责将此链接更新为最新版本。

当API更改(删除新的入口点或更改参数或类型)时,MAJOR通常会增加。对于错误修复版本或在不破坏现有API的情况下引入新的API时,MINOR通常会增加。

在这里可以找到更广泛的讨论: 解剖共享库

61
miguel.de.icaza

共享库应根据以下方案进行版本控制:

blah.so.X.Y.Z

哪里

  • X =向后不兼容的ABI版本
  • Y =向后兼容的ABI版本
  • Z =仅内部更改-ABI不变

通常,您只看到像hello.so.1之类的第一位数字,因为第一位数字是标识库“版本”的唯一条件,因为所有其他数字都向后兼容。

ldconfig维护一个表,其中列出了系统上可用的共享库以及该库的路径所在。您可以通过运行以下命令进行验证:

ldconfig -p

当为Red Hat之类的程序构建软件包时,将在RPM构建时查找并以二进制文件形式调用共享库,并将其添加为该软件包的依赖项。因此,当您去安装软件包时,安装程​​序将通过检查ldconfig来查找hello.so.1是否已安装在系统上。

您可以通过执行以下操作来查看软件包的依赖关系:

rpm -qpR hello.rpm

该系统(与Windows不同)允许将hello.so的多个版本安装在系统上,并同时由不同的应用程序使用。

25
ascotan

libNAME.so是首次查找-lNAME指定的库时编译器/链接器使用的文件名。共享库文件中有一个名为SONAME的字段。当库本身首次通过构建过程链接到共享对象时,将设置此字段。此SONAME实际上是链接程序存储在可执行文件中的内容,具体取决于与该共享库链接的可执行文件。通常,SONAME的格式为libNAME.so.MAJOR,并且只要库与与其链接的现有可执行文件不兼容,便会进行更改,并且可以根据需要保留该库的两个主要版本(尽管只有一个版本指向开发)另外,为了支持在库的次要版本之间轻松升级,libNAME.so.MAJOR通常是指向诸如libNAME.so.MAJOR.MINOR之类的文件的链接。可以安装新的次要版本,一旦完成,指向旧次要版本的链接会被指向新的次要版本,立即升级所有新执行以使用升级的库。另外,请参阅我对 Linux,GNU GCC,ld,版本脚本和ELF二进制格式-如何工作? =

20
penguin359