将一台机器上编译的程序移动到另一台机器并避免库依赖问题

将一台机器上编译的程序移动到另一台机器并避免库依赖问题

当我在 Windows 上编译一个具有依赖项的程序时.dll,只需将那些带有所需程序的 ddls 复制到另一台电脑并将 DLL 放入程序目录中即可。

现在这是我的问题:我使用 clang 和 clang++ 在 Ubuntu 上编译了一个程序,当我将编译的程序传输到我的服务器(CentOS)时,该程序由于缺少库而无法加载。我想将我的库从我的电脑传输到服务器,但我不知道是否可行。

我无法在该服务器上安装程序,因为我没有 root 密码,那么有办法解决这个问题吗?

答案1

任意将.so文件复制到系统范围的目录并不是一个好的做法,因为它将在没有包系统控制意识的情况下将共享库复制到目标系统,因此可能会导致与已安装的软件发生冲突,并且可能缺少其他无法轻松手动映射的依赖项。

您的里程可能会有所不同,但您可以寻找三种不同的方法:

第一个是尝试安装必要的软件包,其中包含目标发行版中库的兼容版本。不过,这需要 root,您表示这不是一个选项。无论如何,如果这在某个时候成为一个选项,这里有一些有助于此方法的提示:ldd you_executable_file显示特定程序的库依赖关系。您可以在提供此类库的发行版中查找软件包(例如,在 Fedora 中,您可以使用yum provides path_to_required_file来告诉您需要安装哪些软件包。

第二个是尝试生成一个与发行版无关的可执行文件。为此,您应该在编译软件时使用静态库。通常,您可以在 Linux 中找到大多数库的共享 (.so) 和静态 (.a) 版本。您应该使用静态版本并将它们链接起来,就好像它们是目标文件 (.o) 一样。缺点是生成的二进制文件比使用共享库时要大得多,因为它将在其内部携带所有库代码。此外,它对稍后安装在系统中的那些库中的错误修复不敏感(这将需要使用新的修复版本重新编译您的程序)。

第三个选项实际上是将库复制到新系统(即使不是 root)到您的主目录下的目录,并使用LD_LIBRARY_PATH和/或LD_PRELOAD环境变量强制动态链接器使用您的库副本。请注意,您可能需要复制许多库(您将使用ldd我上面提到的命令发现这些库)。 LD_LIBRARY_PATH告诉动态链接器查看其他路径以查找丢失的库。 LD_PRELOAD强制动态链接器预加载特定版本的库,覆盖系统范围的版本。

相关内容