在某些情况下,某个程序将依赖库版本x.y,而另一个依赖于x.z,但据我所知,没有一个包管理器允许我同时安装x.y和x.z。有时,它们将允许两个主要版本(如qt4和qt5,它们可以同时安装),但(似乎)绝不允许小版本。
为什么会这样呢?正如所述,什么是阻止它的限制因素?我想一定有一个很好的理由不允许这种看似有用的功能。例如,难道没有字段来说明加载共享对象时要加载的版本,因此Linux不知道如何决定加载哪个版本?还是真的没有理由这么做?就像所有的小版本都应该是兼容的吗?
发布于 2015-06-14 21:29:06
实际上,如果一个共享库运行正常,您可以安装多个版本的共享库。
共享库通常命名如下:
lib<name>.so.<api-version>.<minor>
接下来,有指向库的符号链接,名称如下:
lib<name>.so
lib<name>.so.<api-version>
当开发人员链接到库以生成二进制文件时,链接器找到的是以.so
结尾的文件名。对于任何给定的<name>
,一次只能安装一个库,但这只意味着开发人员不能同时针对多个不同版本的库。对于包管理器,这个.so
符号链接是单独的-dev
包的一部分,只有开发人员才需要安装。
当链接器找到一个以.so
结尾的文件并使用它时,它会在库中查找一个名为soname的字段。soname建议链接器将什么文件名嵌入到生成的二进制文件中,从而建议在运行时查找什么文件名。奏鸣曲应该设置为lib<name>.so.<api-version>
。
因此,在运行时,动态链接器将查找lib<name>.so.<api-version>
并使用它。
其意图是:
<minor>
升级不会改变库的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
和符号链接libmysqlclient.so.16
。libmysqlclient.so.18.0.0
和符号链接libmysqlclient.so.18
。发布于 2015-06-14 21:31:15
这种功能并不是不允许的,只是由于大多数库的编号工作方式以及包名更改带来的不便,这种功能并不常见。
如果使用虚线版本号方案X.Y.Z。“微”版本Z经常在错误修复上更改,则“次要”号Y在向后兼容的更改上更改,而“主”版本号X必须更改API更改(有时还会更改主要额外功能)。
不应该有任何理由不希望修复最新的bug,并且向后兼容的更改也不应该破坏您的软件。
如果库是这样开发的,那么应该始终能够用X(Y+m).(Z+n)替换X.Y.Z。对于任意给定的m和n,您应该总是能够用同一大数列中的最新版本替换您的库。如果库开发人员非常小心,并且下一个主要数字是兼容的(例如,宣布放弃推荐的内容,但尚未删除它们),您甚至可以使用下一个主要数字。
对于包开发人员来说,这意味着他们可以只使用一个名称,甚至没有数字名称,只需更新包就可以给出最新的版本。如果他们在一个包abc2
中发布了一个库,那么他们必须通过循环来移动他们自己的软件,这些软件依赖于abc2
来升级来使用abc3
,有时还带有转换包。如果库中的主版本号适用于大多数依赖的包,则省略主版本号更为方便。因此,即使abc2
和abc3
在发行版中的某个时刻都是可用的,abc3
也经常被称为abc
(就像还没有abc3
时调用abc2
一样),并且一旦发行版中没有依赖于abc2
的包,就有可能完全放弃abc2
。
编号计划并非一视同仁,但我只能想象,随着互联网的到来,传播有关如何使用这类方案的信息,以及图书馆用户(包括发行版开发人员)施加压力,使诸如向后兼容性等重要事项变得清晰,而不必阅读库中包含的更改文件,这些都使这种情况变得更加普遍。
一个反例,但不是库的例子是python,它不兼容它的共享对象和一个小的数字变化的酸洗格式。因此,您将看到python的包( 2.7系列中的最新包)和python3 (当前python3.4系列中的最新包),以及python2.6(不太常见)和python3.3的显式包。
https://unix.stackexchange.com/questions/209710
复制