soname的Debian包命名策略

时间:2016-12-29 15:55:42

标签: ubuntu debian packaging

我正在为一个库制作一个Debian包,我称它为libmystuff。它目前的版本是4.0.0,下一个版本将是4.1.0,可能会破坏API的兼容性。该项目使用CMake构建。

如何在soname和包名中处理它?<​​/ p>

我想最初将软件包版本设为4.0.0。如果我将软件包命名为libmystuff,那么我会收到lintian错误,告诉我将软件包的soname放在软件包名称中(package-name-doesnt-match-sonames)。很公平。

如果我将软件包名称设为libmystuff4,那么我会得到一个名为libmystuff4-dev_4.0.0-1ubuntu8_amd64.deb的软件包文件,这个文件看起来有些多余但是没问题,该软件包适用于主要版本4,软件版本为4.0.0。但我仍然得到一个lintian错误说,

libmystuff4: package-name-doesnt-match-sonames libmystuff4.0.0

所以这对我来说很惊讶,为什么lintian要我将soname的所有3个部分都放在包名中,而不仅仅是第一部分?

在任何情况下,所以我将包名更改为libmystuff4.0.0,现在lintian很安静,但是我得到了一个名为libmystuff4.0.0_4.0.0-1ubuntu8_amd64.deb的包文件,这看起来非常多余!

我该怎么办?

我想也许soname应该是0,即使库版本是4.0.0,并且当他们发布4.1.0等时我应该将soname设置为1.这将需要修补上游CMake构建系统,这是一种可接受的方法吗?虽然在那种情况下,soname的其他部分怎么样,我只是将它们设置为0?然后包将是soname 0.0.0。

否则,当他们发布4.1.0时,我必须将soname更改为5.0.0,这会非常混乱,对吗?

1 个答案:

答案 0 :(得分:1)

简短回答:将当前SONAME设置为libmystuff.so.0,当您在4.1.0中断开ABI时,将SONAME设置为libmystuff.so.1。您需要修补构建系统并在相关位置引入set_property(TARGET mystuff PROPERTY SOVERSION 0 )

您的SONAME 与您的图书馆版本相同,可能需要独立发展。

更长的答案: 库有点尴尬,因为它们有两个独立的方面可以有用地进行版本化:兼容性和二进制兼容性。它们分别是 API ABI 。库版本可以在破坏ABI和二进制不兼容的情况下维护API并保持源兼容,反之亦然。

幸运的是,需要自动化的唯一部分是运行时二进制兼容性。您可以告诉人们阅读API在4.0.0版和4.1.0版之间破坏的文档;您无法告诉运行时动态链接器读取您的文档。

因此SONAME诞生了。链接到库的任何动态对象都嵌入了字符串,它告诉动态链接器要加载哪个库文件来解析符号。

因为它是一个字符串,所以基本上没有要求 - 或者在其中编码的信息。运行时链接器根本不会解释它;它只涉及严格的字符串相等。

这是Lintian警告的来源 - 没有“soname的第一部分”;您的SONAME 字符串 libmystuff.so.4.0.0。 4.0.0部分对人类有意义,而不是链接器。

由于SONAME本质上是任意的,因此惯例在它周围成长,并且惯例是第一版libmystuff的SONAME应该是libmystuff.so.0,然后'。0'应该每次向ABI进行向后不兼容的更改时,增加1。因此,第一个版本为libmystuff.so.0,第二个 ABI libmystuff.so.1,第三个版本为libmystuff.so.2,依此类推。

完全独立于库版本 - 例如,glibc项目目前版本为2.24,并生成一个带有SONAME libc.so.6的库(现在已经做了二十多年了) )。

如果您使用项目的版本作为SONAME,则次更改版本,必须重建使用库的任何内容才能使用新库。针对4.0.0版构建的程序将嵌入字符串 libmystuff.so.4.0.0,并且不会尝试加载libmystuff.so.4.0.1