如何在Linux上部署C++应用程序

4
我的C++应用程序依赖于GCC,MongoDB C++驱动程序和Boost。我目前的方法是保持操作系统一致。我在Ubuntu 12.04 64位桌面版上开发C++,并将其部署在Ubuntu 12.04 64位服务器上。此外,我应该在目标服务器上安装相同版本的依赖项。 但如果我想在Ubuntu 13.04上开发我的C++应用程序,并使用最新的Boost、MongoDB驱动程序和GCC 4.8.1,哪种方式更容易在Ubuntu 12.04服务器上部署C++应用程序。
  1. 静态链接
  2. 动态链接,同时将所有依赖项部署到目标服务器上?
哪种方式更简单?有时候,我无法在目标服务器上编译库。

你有没有考虑使用“cmake”来管理依赖和轻松构建rpm包? - kfsone
2个回答

2
如果依赖项很小,最简单的方法是静态编译所有内容。在构建步骤中非常容易,不需要任何花哨的东西。然而,对于更大的库和更大的项目,这可能会变得不方便。
我认为最佳实践是将依赖项编译成共享对象并将其与二进制文件一起传送,以一种使ld首先查找您的内容的方式执行操作。我认为可以通过例如使用LD_LIBRARY_PATH来实现,例如LD_LIBRARY_PATH=/where/did/i/ship/lib:$LD_LIBRARY_PATH my_binary
这可能有点麻烦,因为您需要设置构建系统以将内容编译为共享对象并正确打包所有内容。
我相当确定一些为Linux提供的预编译程序是以这种方式工作的。奇怪的是,我目前手头找不到任何自定义预编译应用程序。

我现在应该从静态链接开始。这很容易,而且我的应用程序也不是很大。 - Dean Chen

0

这取决于您的应用程序。如果您的应用程序仅由一个特定的二进制文件组成,则需要静态链接所有C++库。您可以安全地动态链接所有C库,因为C ABI是不变的;这只留下了版本依赖性。但是,在大多数情况下,主要SO-Name版本大多兼容,并且具有不同主要SO-Name的库可以并行安装。因此,我会依赖软件包管理器来安装它们。由于缺乏共同的ABI,C++库很棘手。即使是编译器版本的微小升级也可能导致它们不兼容。


1
虽然正确的方法是为该Linux发行版实际制作一个软件包。 - user405725
@VladLazarenko:在Blender项目中,决定制作一个普遍适用的tarball分发包比制作软件包更好。我必须同意这个决定,因为发行版可以轻松地从中制作软件包,而使用小众发行版的人也可以使用它。 - datenwolf
没错。但是想象一下,如果所有的软件包都静态链接其所有依赖关系,那将会是一场大混乱。像往常一样,这两种方法都有优缺点 :) - user405725
@VladLazarenko:实际上,这会大大减少混乱。有不少计算机科学家和程序员(比如著名的John Carmack)得出结论,引入动态链接是一个错误。关于这个问题的一个很好的概述可以在http://harmful.cat-v.org/software/dynamic-linking/找到。 - datenwolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接