处理 Linux 上的库依赖关系



我在我的项目中使用libcurl,它依赖于openssl和运行时中的一堆其他.so。
这种依赖性有点痛苦,因为不同的发行版/版本可能包含不同的openssl版本。

例如,如果我在 Ubuntu 9.10 上编译我的应用程序,我在 Ubuntu 11.10 上运行时遇到问题。

看到了两种如何解决此问题的选项,但对于我的情况来说,它们都不够好:

  1. 打包我的应用程序,让包管理器解决这类问题

  2. 静态链接所有部门

我的应用程序真的很小,打包/维护它会矫枉过正。另外,其中一个要求是它应该是可下载和运行的。所以,(1(对我来说不是一个选择。

静态链接 (2( 将是不错的解决方案,但似乎没有 libopenssl、libcrypto 和 libcurl 附带的其他传递依赖项的静态二进制分布。

从理论上讲,我可以尝试手动在libcurl后面构建所有库动物园,但这似乎会使维护变得更加复杂。

所以,这里有一个问题——我错过了什么吗?有没有一种不那么痛苦的方法可以在 linux 世界(具体来说就是 Ubuntu(中以更少的痛苦做我想做的事情?欢迎任何建议。

我在我的项目中使用 libcurl,它取决于 openssl 和 bunch 运行时中的其他 .so。这种依赖是一种痛苦, 由于不同的发行版/版本可能包含不同的 openssl 版本。

例如,如果我在 Ubuntu 11.10 上运行时遇到问题 在 Ubuntu 9.10 上编译我的应用程序。

首先,这有什么问题?如果你从旧版本的 Ubuntu 升级到新版本,你应该没有问题。如果我没记错的话,你只需要指定你需要的库的最低版本,包管理器应该能够安装合适的版本。较新版本的库不应破坏现有应用,除非使用的是已弃用的功能。

我的应用程序真的很小,打包/维护它会矫枉过正。加 其中一个要求是它应该是可下载和运行的。 所以,(1(对我来说不是一个选择。

对于Linux(尤其是Ubuntu,Fedora和其他顶级发行版(,打包实际上是分发应用程序的方式。下载-安装-运行是Windows的事情,这不是Linux上的人安装软件的方式(好吧,Linux新手可能......(

您还应该尝试接受发行版,这将随着时间的推移减轻您的负担。至少在 Ubuntu 上,实现这一目标的第一步是创建自己的 PPA(https://help.launchpad.net/Packaging/PPA(。

静态链接(2(将是不错的解决方案,但似乎有 没有 libopensssl、libcrypto 和其他的静态二进制分布 libcurl 附带的传递依赖项。

这通常是一件非常非常糟糕的事情。 静态链接或仅将库与您的应用程序捆绑在一起会给您带来更新它的负担,如果您不更新这些内容,就会产生影响。所以,我不推荐这种方法。有关更多详细信息,请参阅此处:http://www.dwheeler.com/blog/2012/04/03/#insecure-libraries

这是 Fedora 的政策: http://fedoraproject.org/wiki/Packaging:No_Bundled_Libraries

所以,这里有一个问题——我错过了什么吗?有没有少 在 Linux 世界中做我想做的事的痛苦方式(具体来说就是 Ubuntu( 疼痛减轻?欢迎任何建议。

这里确实有两件事要做:

  1. 打包:理想情况下,这将是 Ubuntu/Debian 的 deb 和 Fedora/Suse 的 rpm。另一种流行的替代方法是使用自动工具(autoconf/automake(,以便用户可以使用所需的先决条件构建应用程序。最后一个选项是只提供一个生成文件和一个自述文件,并期望您的用户做正确的事情。
  2. 分发:理想情况下,这是发行版存储库。Ubuntu PPA是一个很好的起点。另一种方法是在您自己的站点上托管二进制文件/包。

大多数流行的应用程序既为流行的 Linux 发行版提供 .deb/.rpm,也为具有不同打包系统的发行版提供自动工具.tar.gz。

最后,让我问你这个问题:你的重点是让你提供你的应用程序减少痛苦,还是让你的用户获得你的应用程序不那么痛苦?

还有第三个选项:

创建适合您需求的某种存档,并包含您需要的 .so/.dll 文件,具体取决于平台。ZIP存档应该适用于Linux和Windows。

然后在 Linux 安装的包装脚本中使用 LD_LIBRARY_PATH(它允许您将 .so 文件放在某个特殊位置,通常是在 libs 目录中(。据我所知,Windows使用CWD作为查找二进制文件所需的.dll文件的第一个位置,因此您需要做的就是将它们放在与二进制文件相同的目录中,然后您就可以开始了。

使用这种方法,您可以保持较小的"分布",并且不需要静态链接或任何其他特殊处理。

只要确保分析.so/.dll文件的实际依赖链,以便在目标环境中加载某些意外库时不会感到惊讶。

你考虑过使用 qt 吗?你根本不会遇到这些问题,而且它们对 ssl 和 http

  1. 使用操作系统中的 .so 文件(共享库(,并建议用户使用"至少版本 x"。这几乎可以照顾好一切。

  2. 将非共享(静态(库(.a 文件(与应用程序捆绑在一起,或将共享库(.so 文件(与应用程序捆绑在一起。

静态 .a 文件非常简单,可以使用 ./configure 脚本从源代码构建。您可以轻松获取.so文件,但是将它们与您的应用程序捆绑在一起需要相当多的技巧。可以修补 .so 文件;它们内部有路径,说明应该从哪里加载依赖项。因此,捆绑 .so 文件并非不可能,甚至可能是避免为一系列依赖项构建 .a 文件的手动步骤的便捷方法 - 如果您找到并使用脚本来重新定位 .so 文件。

你写:

从理论上讲,我可以尝试手动在libcurl后面构建所有库,但这似乎会使维护变得更加复杂。

是的,它会的,因为您需要安全补丁,对吧?所以最好的方法是#1 - 让用户安装他可以获得的最新版本,并负责确保他的系统安全。

当您遇到为无法使用解决方案 #1 的客户执行自定义工作的情况时,解决方案 #2 很方便。在这里,您可以按计划提供软件的定期版本,包括最新的依赖项及其所有修复程序。小型软件通常会达到不再需要更改的地步。对于一小部分软件来说,此解决方案不是一个好的解决方案,因为您的软件没有更改,但您仍然进行定期发布,仅仅是因为依赖项有更新。因此,除非您的客户确实需要,否则不要使用此解决方案。从长远来看,它更昂贵。

希望这有帮助!

最新更新