5

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

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

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

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

  2. 静态链接所有部门

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

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

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

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

4

4 回答 4

3

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

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

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

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

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

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

静态链接 (2) 将是不错的解决方案,但似乎没有 libopenssl、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),以便用户可以使用所需的先决条件构建您的应用程序。最后一个选项是只提供一个 Makefile 和一个 README 并期望您的用户做正确的事情。
  2. 分发:理想情况下,这是与发行版存储库一起使用的。Ubuntu PPA 是一个很好的起点。另一种方法是在您自己的站点上托管二进制文件/包。

大多数流行的应用程序都为流行的 Linux 发行版提供 .deb/.rpm 以及带有自动工具的 .tar.gz,用于在具有不同打包系统的发行版上构建。

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

于 2012-05-06T15:52:34.837 回答
1

还有第三种选择:

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

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

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

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

于 2012-05-03T10:06:56.807 回答
0

你考虑过使用qt吗?你根本就不会有这些问题,而且它们对 ssl 和 http 有强大的 rmeasy 支持

于 2012-05-03T07:43:15.880 回答
0

所以你问“有没有更痛苦的方法”。我喜欢其他答案,尤其是 Naveen 的答案。所以你有两个解决方案

  1. 使用操作系统中的 .so 文件(共享库)并向您的用户推荐他们使用“至少版本 x”。这几乎可以解决所有问题。

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

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

你写:

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

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

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

希望这可以帮助!

于 2013-11-26T13:33:49.090 回答