Solaris:.so和.so.1文件有什么区别?

我想了解如何/为什么某些库文件由Solaris上的链接器dynamic加载。 我正在使用ldd来查看(使用-s开关查看链接器尝试了哪些path)。 例如,如果我运行“ldd / usr / local / bin / isql -s”,我注意到其中一个search的库被称为“libodbc.so.1”。 我注意到这不匹配它沿着“libodbc.so”的方式find的文件。 因此,它终于解决了在“libodbc.so.1.0.0”和“libodbc.so.1”之间存在符号链接的地方。 我的问题是 – 这里“.1”的意义是什么? 它是指示一个版本号? 为什么有些安装程序会创build这些符号链接,而另一些则不是?

这个问题不是特定于Solaris的。

当你安装一个共享库(或一个提供共享库的软件)时,你会得到三个文件,它们看起来都很相似,但是有不同的用途。

  • libfoo.so.1.0.0 – 这是(常规的)数据文件。 它包含图书馆本身。 你可以有多个不同的版本。 在这个文件里面,有一个叫做SONAME的ELF字段 ,它被设置为libfoo.so.1 。 在Linux上,运行objdump -p libfoo.so.1.0.0 | grep SONAME objdump -p libfoo.so.1.0.0 | grep SONAME找出来。
  • libfoo.solibfoo.so.1.0.0 – 这是在针对libfoo编译软件时使用的符号链接。 当你指定链接器的时候,它会查找libfoo.so 。 通常情况下, libfoo.so永远不是一个普通的文件,它总是一个符号链接,指向你想用于链接的libfoo版本。 在复杂的构build环境中,可以有多个版本的库,并使用此符号链接来select要链接的版本。
  • libfoo.so.1libfoo.so.1.0.0 – 这也是一个符号链接,在运行需要你的库的二进制文件时使用。 还记得我提到的SONAME字段吗? 当你将一个二进制文件链接到libfoo时,二进制文件将会logging这个库的SONAME,并在运行时使用它。

该设置允许您将多个版本的相同库安装在一起。 不同的二进制文件可能需要不同版本的库,每个二进制文件都会find正确版本的库。 通常情况下,当存在向后不兼容的API更改时,库的SONAME被上游更改。 所有旧的二进制文件仍然使用旧的API,而新的链接的二进制文件使用新的二进制文件。

一些打包项目,Debian就是一个例子,为不同版本的库使用不同的软件包名称 。 这使您可以独立安装和卸载共享库的每个版本。

有一些边缘情况。 例如,共享库之间的依赖关系可能会导致同时引入两个版本。 考虑:

 foo → libbar.so.1, libbaz.so.1 libbar.so.1 → libbaz.so.1 

想象一下,我们安装一个新版本的libbaz并重新编译foo。 现在我们有:

 foo → libbar.so.1, libbaz.so.2 libbar.so.1 → libbaz.so.1 

在运行时,foo将加载libbaz.so.2libbar.so.1 ,而libbar.so.1将加载libbaz.so.1 。 看到问题? 两个libbaz版本同时加载。 我不完全确定内存中代码布局的确切后果,但实际上这会导致崩溃。

是的,“.1”表示版本号。 这使得可以并排存储多个版本的相同库,而最常见的版本具有没有版本号的链接。

如果不需要区分不同版本,则版本后缀可能不存在。