部署依赖于共享库的Linux应用程序的可接受方法是什么?

我有一个依赖于Qt, GDCM和VTK的应用程序,主要的构build环境是Qt。 所有这些库都是跨平台的,可以在Windows,Mac和Linux上编译。 在Windows上部署后,我需要将应用程序部署到Linux。 我使用的vtk和gdcm版本是git(大约一个月前)的中继版本,比我能在Ubuntu 11.04上得到的更新,这是我当前(也是唯一)的Linux部署目标。

部署依赖于这些库的应用程序的公认方法是什么?

我应该在这里静态链接,以避免LD_LIBRARY_PATH? 我在LD_LIBRARY_PATH上看到有冲突的报告; 像这样的教程表明,这是修改库path以通过系统重启使用共享库的“正确方法”。 其他人 build议我不应该设置LD_LIBRARY_PATH。 在GDCM的默认版本中,安装程序已经把库放到/usr/local/lib目录下,所以当我运行ldd <my program>时候,这些库会被看到。 另一方面,VTK将它的库放到/usr/local/lib/vtk-5.9 ,这个文件不是大多数用户机器上的LD_LIBRARY_PATH的一部分,所以除非对系统进行了一些修改。 将VTK文件复制到“/ usr / local / lib”不允许“ldd”查看文件。

那么,如何让我的应用程序看到VTK使用库?

在windows上,部署dll非常简单,因为我可以将它们包含在安装程序中,应用程序可以find它们,因为它们位于本地目录中。 这种方法在Linux中不起作用,所以我要让用户从任何适当的源代码安装Qt,GDCM和VTK,并使用默认位置,然后让应用程序指向这些默认位置。 但是,由于VTK将事物放入非标准位置,我是否也希望用户修改LD_LIBRARY_PATH? 我应该包括我想要的特定版本的库,然后弄清楚如何使可执行文件在这些库的本地目录中查找,并忽略在库path中find的那些文件?

我见过的每一个“严肃的”商业应用程序都使用LD_LIBRARY_PATH 。 它们总是包含一个如下所示的shell脚本:

 #!/bin/sh here="${0%/*}" # or you can use `dirname "$0"` LD_LIBRARY_PATH="$here"/lib:"$LD_LIBRARY_PATH" export LD_LIBRARY_PATH exec "$0".bin "$@" 

他们将这个脚本命名为.wrapper并创建一个如下.wrapper的目录树:

 .wrapper lib/ (directory full of .so files) app1 -> .wrapper (symlink) app1.bin (executable) app2 -> .wrapper (symlink) app2.bin (executable) 

现在你可以复制这棵树到你想要的任何地方,你可以运行“/ path / to / tree / app1”或者“/ path / to / tree / app2 –with –some –arguments” 。 所以将路径/路径/到/树。

顺便说一句,这也是Firefox和Chrome如何做,或多或少。

谁告诉你不要使用LD_LIBRARY_PATH是充满了,恕我直言。

你想放在哪个系统库取决于你想正式支持哪个Linux版本。

甚至不要考虑静态链接。 glibc开发者不喜欢它,他们不关心支持它,而且在每次发布的时候它们都设法打破它。

祝你好运。

一般来说,最好的选择是依赖于正常版本的库,无论你的目标是什么发行版(并且说你不支持不支持最近版本的lib的dists),但是如果你真的需要依赖一些共享库的最新版本,你可以用-Wl,-rpath,'$ORIGIN'链接你的应用程序,然后在你的可执行文件所在的目录下安装你想要的确切版本的副本。

请注意,如果使用make,则makefile中需要$$才能将实际发送给链接器的参数放入$ 。 单一的qutoes是必要的,所以外壳不会碰到东西…

那么,有两种选择来部署Linux应用程序。

正确的方法是:

  • 为您的应用程序和库创建一个包,如果它们如此特殊,那么它们不能从标准库中安装

  • 有两种主要的软件包格式。 RPM和DEB。

简单的方法:

  • 制作一个自解压文件,将“windows方式”安装到/opt

  • 您可以将库与可执行文件放在同一个目录中,这不是首选的方法。