在一个 Debian 软件包中支持多个 Boost 版本

Posted

技术标签:

【中文标题】在一个 Debian 软件包中支持多个 Boost 版本【英文标题】:Supporting multiple Boost versions in a Debian Package 【发布时间】:2013-07-16 16:11:47 【问题描述】:

我正在尝试为我的一个项目创建一个 debian 包,但遇到了 boost 版本支持的问题。

已经确实看过this的问题。它是相似的,但提供的解决方案(Build-Depends)并不真正适用于我,因为我正在制作二进制安装程序。

基本上,我安装的库和可执行文件总是链接到 libboost_(component).so.1.46 而不是符号链接库 libboost_(component).so。让我的 debian 安装程序只能由使用我的确切 boost 版本的人使用。我正在使用 CPack 制作 debian 包,我的依赖行如下所示:

SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-dev (>= 1.46),
                                  libboost-thread-dev (>= 1.46),
                                  libboost-signals-dev (>= 1.46),
                                  libboost-system-dev (>= 1.46), 
                                  libboost-filesystem-dev (>= 1.46),
                                  libboost-python-dev (>= 1.46), ..." )

我是否需要为所述平台上的每个平台或使用该平台的增强版本构建单独的安装程序?

【问题讨论】:

【参考方案1】:

虽然我理解你想要创建一个适用于所有 boost 版本的包的意图,但你真的必须问问自己这是否真的可行。

.so 版本的想法(例如.so.1.46 vs .so.1.48)实际上是为了表明库接口(ABI)has changed,这基本上表明库不兼容。

因此,极不可能链接到libboost_foo.so.1.46 的应用程序实际上将与libboost_foo.so.1.48 一起工作。 很可能,您的应用程序所需的符号突然消失了(因此您的应用程序将拒绝启动)。更糟糕的是,可能是符号的含义在版本之间发生了变化,导致难以跟踪未定义的行为。

这就是为什么每当您链接到 libfoo.so 时,二进制文件确实链接到 libfoo.so.1(或 libfoo.so 真正指向的任何位置)

现在debian policy 是,对于任何不兼容的 ABI 更改,必须更改包名称。这基本上允许用户同时安装同一个库的两个版本(例如 boost-1.46 和 boost-1.49)。

如果您以特定版本的 Debian 为目标,您可以确保特定版本的库可用。例如在 Debian/wheezy 上,您将拥有 boost-1.49。 所以如果你提供来自 Debian/wheezy 的软件包,你只需要链接 boost-1.49。 这也是版本如此出色的原因之一:它可以保证所有需要的图书馆都可用。

这也意味着,您可以在多个 Debian 版本中拥有同一应用程序的不同软件包版本,即使没有“上游”版本:软件包必须重新构建,因为依赖项的升级(涉及 soname 更改)

总结如下:

链接到实际库版本是一项功能,可让您的系统保持正常

debian 允许同时安装同一个库的多个版本

您的问题的解决方案:

为任何依赖项的每个 soname 版本提供二进制包

为每个 debian 发行版提供软件包将使这比看起来麻烦得多(因为每个发行版只有一组固定的库)。

【讨论】:

感谢您的回复。奇怪的是,我的应用程序实际上与 boost 1.46、1.48 和 1.49 一样正常工作。看来我的选择是(a)为每个我想要支持的 Ubuntu 版本构建一个新的 debian 安装程序,或者(b)在每台机器上安装 boost 1.46,即使它有更高的 boost 版本。我认为 (a) 听起来是一个更好的选择,而且可能值得一试。 “按原样工作”是什么意思?您能否再次编译您的应用程序任何版本的 boost,或者即使您将libboost_foo.so.1.46.0libboost_foo.s.1.49.0 交换,它是否仍能继续工作?无论如何,如果它确实有效,那只是运气(这取决于您真正从库中导入了多少符号)。 无论如何,你的解决方案 (a) 确实是要走的路(虽然我不知道在这个游戏中 ubuntu 在哪里替换了 debian :-)) 我的意思是人们已经针对多个版本的 boost 编译、链接和运行我的源代码而没有问题。我想我很幸运能够使用尚未收到 API 更新的 boost 组件。就像你说的那样,我会因为这个原因尝试选择(a)。 您的经验表明 boost(或至少您正在使用的部分)保持 API 兼容性;这与 ABI 兼容性没有直接关系。 (使用一些宏很容易拥有完全不同的 API(源代码中的符号)和 ABI(链接器级别的符号)【参考方案2】:

你可以尝试做的是静态链接 boost 包:

设置(Boost_USE_STATIC_LIBS ON)

【讨论】:

以上是关于在一个 Debian 软件包中支持多个 Boost 版本的主要内容,如果未能解决你的问题,请参考以下文章

Linux(Ubuntu/Debian/CentOS/RedHat)下交叉编译boost库

Debian Squeeze 中是不是默认安装了 Boost 头文件库?

哪个linux系统好用

linux系统哪个版本好

使用 cmake 创建多个 Debian 软件包

debian11中无法下载bind