部署依赖共享库的 linux 应用程序的公认方法是什么? [英] What's the accepted method for deploying a linux application that relies on shared libraries?

查看:19
本文介绍了部署依赖共享库的 linux 应用程序的公认方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个依赖于 Qt 的应用程序、GDCMVTK,主要构建环境是 Qt.所有这些库都是跨平台的,可以在 Windows、Mac 和 Linux 上编译.在 Windows 上部署后,我需要将应用程序部署到 Linux.我使用的 vtk 和 gdcm 版本是来自 git 的主干版本(大约一个月前),比我在 Ubuntu 11.04 上获得的 apt-get 更新,这是我当前(也是唯一的)Linux 部署目标.

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

我应该在这里静态链接以避免 LD_LIBRARY_PATH 吗?我在 LD_LIBRARY_PATH 上看到相互矛盾的报告;像这个这样的教程表明这是修改库路径以使用共享库的正确方法"系统重新启动.其他 建议 我不应该设置 LD_LIBRARY_PATH.在 GDCM 的默认版本中,安装已经将库放入 /usr/local/lib 目录中,因此当我运行 ldd 时可以看到这些库.另一方面,VTK 将其库放在 /usr/local/lib/vtk-5.9 中,它不是大多数用户机器上 LD_LIBRARY_PATH 的一部分,因此除非进行一些更改,否则无法找到对系统做出的.将 VTK 文件复制到/usr/local/lib"不允许ldd"看到这些文件.

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

在 Windows 上,部署 dll 非常简单,因为我只需将它们包含在安装程序中,应用程序就会找到它们,因为它们位于本地目录中.这种方法在 Linux 中不起作用,所以我打算让用户从任何合适的源安装 Qt、GDCM 和 VTK,并使用默认位置,然后让应用程序指向这些默认位置.但是,既然 VTK 把东西放到了一个非标准的位置,我是否也应该期望用户修改 LD_LIBRARY_PATH?我是否应该包含我想要的库的特定版本,然后弄清楚如何使这些库的本地目录中的可执行文件看起来并忽略它在库路径中找到的那些?

解决方案

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

#!/bin/shhere="${0%/*}" # 或者你可以使用`dirname "$0"`LD_LIBRARY_PATH="$here"/lib:"$LD_LIBRARY_PATH"导出 LD_LIBRARY_PATH执行$0".bin$@"

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

.wrapperlib/(包含 .so 文件的目录)应用程序 1 ->.wrapper(符号链接)app1.bin(可执行文件)app2 ->.wrapper(符号链接)app2.bin(可执行文件)

现在你可以将整棵树复制到任何你想要的地方,你可以运行/path/to/tree/app1"或/path/to/tree/app2 --with --some --arguments"和它会起作用.将/path/to/tree 放在您的 PATH 中也是如此.

顺便说一句,Firefox 和 Chrome 或多或少也是这样做的.

谁告诉你不要使用 LD_LIBRARY_PATH 的,恕我直言.

你想在 lib 中放入哪些系统库取决于你想要正式支持的 Linux 版本.

甚至不要考虑静态链接.glibc 开发人员不喜欢它,他们不关心支持它,而且他们设法在每次发布时更努力地打破它.

祝你好运.

I have an application that relies on Qt, GDCM, and VTK, with the main build environment being Qt. All of these libraries are cross-platform and compile on Windows, Mac, and Linux. I need to deploy the application to Linux after deploying on Windows. The versions of vtk and gdcm I'm using are trunk versions from git (about a month old), more recent than what I can get apt-get on Ubuntu 11.04, which is my current (and only) Linux deployment target.

What is the accepted method for deploying an application that relies on these kinds of libraries?

Should I be statically linking here, to avoid LD_LIBRARY_PATH? I see conflicting reports on LD_LIBRARY_PATH; tutorials like this one suggest that it's the 'right way' to modify the library path to use shared libraries through system reboots. Others suggest that I should never set LD_LIBRARY_PATH. In the default version of GDCM, the installation already puts libraries into the /usr/local/lib directory, so those libraries get seen when I run ldd <my program>. VTK, on the other hand, puts its libraries into /usr/local/lib/vtk-5.9, which is not part of the LD_LIBRARY_PATH on most user's machines, and so is not found unless some change is made to the system. Copying the VTK files into '/usr/local/lib' does not allow 'ldd' to see the files.

So, how can I make my application see VTK to use the libraries?

On windows, deploying the dlls is very straightforward, because I can just include them in the installer, and the application finds them because they are in the local directory. That approach does not work in Linux, so I was going to have the users install Qt, GDCM, and VTK from whatever appropriate source and use the default locations, and then have the application point to those default locations. However, since VTK is putting things into a non-standard location, should I also expect users to modify LD_LIBRARY_PATH? Should I include the specific versions of the libraries that I want and then figure out how to make the executable look in the local directory for those libraries and ignore the ones it finds in the library path?

解决方案

Every "serious" commercial application I have ever seen uses LD_LIBRARY_PATH. They invariably include a shell script that looks something like this:

#!/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 "$@"

They name this script something like .wrapper and create a directory tree that looks like this:

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

Now you can copy this whole tree to wherever you want, and you can run "/path/to/tree/app1" or "/path/to/tree/app2 --with --some --arguments" and it will work. So will putting /path/to/tree in your PATH.

Incidentally, this is also how Firefox and Chrome do it, more or less.

Whoever told you not to use LD_LIBRARY_PATH is full of it, IMHO.

Which system libraries you want to put in lib depends on which Linux versions you want to officially support.

Do not even think about static linking. The glibc developers do not like it, they do not care about supporting it, and they somehow manage to break it a little harder with every release.

Good luck.

这篇关于部署依赖共享库的 linux 应用程序的公认方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆