处理linux上的库依赖项

时间:2012-05-03 07:22:20

标签: c++ linux dependencies openssl libcurl

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

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

我看到两个选项如何解决这个问题,但对我的情况来说,这些选项都不够好:

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

  2. 静态链接所有deps

  3. 我的应用程序非常小,打包/维护它会有点矫枉过正。此外,其中一个要求是它应该可以下载并运行。所以,(1)对我来说不是一个opton。

    静态链接(2)可能是一个不错的解决方案,但似乎没有libopenssl,libcrypto和libcurl附带的其他传递依赖的静态二进制发行版。

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

    所以,这是问题 - 我错过了什么吗?是否有一种不那么痛苦的方式来做我想要的Linux世界(Ubuntu具体),减少痛苦?欢迎任何建议。

4 个答案:

答案 0 :(得分:3)

  

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

     

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

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

  

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

对于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和Fedora / Suse的转换,这将是deb。另一种流行的替代方法是使用autotools(autoconf / automake),以便用户可以使用所需的pre-req构建应用程序。最后一个选项是提供Makefile和README,并希望您的用户做正确的事情。
  2. 分发:理想情况下,这是发行版存储库。 Ubuntu PPA是一个很好的起点。另一种方法是在您自己的站点上托管二进制文件/包。
  3. 大多数流行的应用程序都为流行的Linux发行版提供.deb / .rpm以及带有autotools的.tar.gz,用于构建具有不同打包系统的发行版。

    最后,请允许我问你:您是否专注于减少提供应用程序的痛苦,或者减少用户获取应用程序的痛苦?

答案 1 :(得分:1)

还有第三种选择:

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

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

使用此方法,您可以保持“分布”较小,无需静态链接或任何其他特殊处理。

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

答案 2 :(得分:0)

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

有强大而又狡猾的支持

答案 3 :(得分:0)

所以你问“是否有一种不那么痛苦的方式。”我喜欢其他答案,尤其是Naveen的回答。所以你有两个解决方案

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

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

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

    你写道:

      

    理论上我可以尝试手动构建libcurl背后的libs动物园,但似乎这会使维护变得更加复杂。

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

    当您遇到无法使用解决方案#1的客户进行自定义工作的情况时,解决方案#2非常方便。在这里,您可以按计划定期发布软件,包括最新的依赖项及其所有修复程序。小软件通常会停止需要更改。这个解决方案对于一小块软件来说不是一个好的解决方案,因为你的软件没有改变,但你仍然只是因为依赖关系有更新而定期发布。因此,除非客户实际需要,否则不要使用此解决方案。从长远来看,它更贵。

    希望这有帮助!