2016-12-29 115 views
0

我为一个库制作Debian软件包,我将其称为libmystuff。目前它的版本是4.0.0,下一个版本是4.1.0,可能会破坏API的兼容性。该项目使用CMake来构建。soname的Debian软件包命名策略

这应该怎么处理soname和包名?

我想将软件包版本初始化为4.0.0。如果我命名包libmystuff,那么我得到一个lintian错误,告诉我把包的soname放在包名(package-name-doesnt-match-sonames)中。很公平。

如果我将包名称为libmystuff4,那么我会得到一个名为libmystuff4-dev_4.0.0-1ubuntu8_amd64.deb的包文件,它似乎有点多余但可以,包是用于主版本4,软件是版本4.0.0。但我仍然获得了林田错误说,

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

所以这令我感到诧异,为什么林田要我把所有3个部分的soname的包名称,而不是仅仅是第一部分?

在任何情况下,所以我将包名改为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

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

您的SONAME是而不是与您的图书馆版本相同,可能需要独立进化。

较长答案: 库是在有点别扭他们有两个分立面,可以有效地进行版本:兼容性,和二进制兼容性。这些分别是APIABI。一个库版本可以维护API并且与源代码兼容,同时打破ABI并且与二进制不兼容,反之亦然。

幸运的是,需要自动执行的唯一部分是运行时二进制兼容性。您可以告诉人们阅读您的文档,说明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'应该每次增加1向ABI做出向后不兼容的变更。所以第一个版本是libmystuff.so.0,第二个ABIlibmystuff.so.1,第三个ABI是libmystuff.so.2等等。

这是完全独立的库版本 - 例如,glibc的项目目前是在2.24版本,并产生与SONAME libc.so.6库(并做了二十多年了)。

如果您使用项目的版本作为SONAME,然后时间您更改版本任何使用该库的任何内容必须重建,以便使用新的库。一个针对版本4.0.0构建的程序将嵌入字符串libmystuff.so.4.0.0,并且不会尝试加载libmystuff.so.4.0.1