Answers:
实际上,如果正确完成,您可以安装共享库的多个版本。
共享库通常命名如下:
lib<name>.so.<api-version>.<minor>
接下来,有以下名称的库符号链接:
lib<name>.so
lib<name>.so.<api-version>
当开发人员针对该库进行链接以生成二进制文件时,.so
链接器将找到以该文件名结尾的文件名。实际上,对于任何给定<name>
,一次只能安装其中的一个,但这仅意味着开发人员无法同时定位库的多个不同版本。对于软件包管理器,此.so
符号链接是单独的-dev
软件包的一部分,只有开发人员才需要安装。
链接器找到名称以结尾的文件.so
并使用该文件时,它将在该库中查找名为soname的字段。soname建议链接器将什么文件名嵌入到生成的二进制文件中,从而在运行时查找什么文件名。该soname应该设置为lib<name>.so.<api-version>
。
因此,在运行时,动态链接器将查找lib<name>.so.<api-version>
并使用它。
目的是:
<minor>
升级不会更改库的API,并且当库的API升级<minor>
到更高版本时,可以安全地将所有二进制文件升级到新版本。由于二进制文件都在lib<name>.so.<api-version>
名称下搜索库,这是最新安装的符号链接lib<name>.so.<api-version>.<minor>
,因此它们得到了升级。<api-version>
升级会更改库的API,让现有的二进制应用程序使用新版本并不安全。在<api-version>
更改的情况下,由于这些应用程序正在寻找名称,lib<name>.so.<api-version>
但是的值不同<api-version>
,因此它们不会选择新版本。包管理器通常不会在同一发行版中打包同一库的一个以上版本,因为在发行版发行之前,整个发行版(包括使用该库的所有二进制文件)通常都被编译为使用每个库的一致版本。已发布。确保所有内容都是一致的,并且分发中的所有内容都与其他所有内容兼容,这对于分发者来说是很大的工作量。
但是,如果您已经将系统从发行版的一个版本升级到另一个版本,并且仍然有一些需要较早版本库的较旧软件包,则可以轻松获得库的多个版本。例:
libmysqlclient.so.16.0.0
和symlink libmysqlclient.so.16
。libmysqlclient.so.18.0.0
和symlink libmysqlclient.so.18
。不允许使用此功能,这是由于大多数库编号工作方式以及软件包名称更改不便而导致的,因此并不十分常见。
如果使用点分版本号方案XYZ,“微型”版本Z经常会在错误修正时发生更改,“次要”版本Y会在向后兼容更改时发生更改,而“主要”版本号X在API更改时必须发生更改(有时会在主要的额外功能)。
永远没有理由不希望您解决最新的错误,并且向后兼容的更改也不会破坏您的软件。
如果以这种方式开发库,则应该始终可以用X.(Y + m)。(Z + n)替换XYZ。对于任何给定的m和n。也就是说,您应该总是能够用相同的主要数字系列中的最新图书馆来代替您的图书馆。而且,如果库开发人员非常谨慎,并且下一个主要编号是兼容的(例如通过公告弃用但尚未删除它们),您甚至可以使用下一个主要编号。
对于软件包开发人员来说,这意味着他们可以仅使用一个名称,甚至不使用任何数字名称,只需更新软件包即可为您提供最新版本。如果他们以套件的形式运送库,abc2
那么他们就必须经过箍才能移动自己的软件,这些软件依赖于abc2
升级才能使用abc3
,有时还带有过渡套件。如果该库适用于大多数依赖的软件包,则从库中省去主要版本号更为方便。因此,即使两者abc2
和abc3
应该在某个发行版中可用的某个点上都可用,abc3
也经常被调用abc
(就像abc2
在abc3
尚不存在时被调用一样),并且一旦没有软件包依赖abc2
于发行版,就有可能丢弃abc2
共。
编号方案不是统一遵循的,但是我只能想象随着互联网的到来,传播有关如何使用这种方案的信息,以及图书馆用户(包括发行商)施加压力,使诸如向后兼容之类的重要事情变得清晰起来,而又没有不得不阅读库中包含的CHANGES文件,这导致这种情况变得越来越普遍。
一个反例但不是库的反例是python intpreter,它在其共享对象和次要数字更改时的酸洗格式上不兼容。因此,您将看到python(2.7系列中的最新版本)和python3(当前python3.4系列中的最新版本)软件包,以及python 2.6(并不少见)和python 3.3的显式软件包。