语境:
在最近对我们的一系列服务器软件进行了版本升级之后,我发现自己陷入了一个困境:
我有两套应用程序(Zend 服务器和各种实用程序,以及一堆 PostgreSQL 管理实用程序),它们都大量使用某个库文件(libpq.so)。Zend 附带了自己的 libpq,这是我发现的唯一一个可以与所有 Zend 内容一起使用的版本。Postgres 也附带了自己的库版本。这两者是互斥的:如果 Postgres 的库版本在执行某项操作的用户的 LD_LIBRARY_PATH 中排在第一位,则所有 Postgres 实用程序都可以工作,但 Zend 的实用程序都不能工作。如果 Zend 的版本排在第一位,则 Zend 的内容可以工作,但 Postgres 的内容则不行。
这两个库的名称相同。PostgreSQL 兼容库包不起作用。
在我们的环境中,这两组应用程序都在许多不同的 CentOS 机器上在许多不同的、不可预测的用户帐户下使用,因此使用“正确的方式”并为每个用户设置 LD_LIBRARY_PATH,并告诉人们“仅在 Y 帐户下使用 X 应用程序”是行不通的。
问题:
有没有每个应用程序有没有什么方法可以说“对于在 X 文件夹中执行的这些二进制文件/应用程序,链接到路径 Y 处的库,但对于其他二进制文件,链接到库 Z”?基本上,每个应用程序的库路径,无需每次访问其中一个应用程序时都设置 LD_LIBRARY_PATH 或 DYLD_*。
我希望避免重新编译库,因为每当有新版本的软件发布时,我都会面临大量额外的麻烦和测试。我已经有了可以运行的库,只是它们不能同时适用于这两组应用程序。
答案1
嵌入的搜索路径
有一个选项可以满足您的要求:
构建应用程序时,您可以设置LD_RUN_PATH
环境变量,该变量将被编译到应用程序中。理论上,该chrpath
命令将允许您修改应用程序中的嵌入路径没有需要重新编译它,但我自己从未测试过。
chrpath
在 Fedora 中可用,但是我找不到该来源的权威来源。
您提到了DYLD_*
变量,这表明您在 OS X 下工作,在这种情况下,上述内容可能不适用于您。这对于 Linux 来说当然是正确的,但 OS X 运行时链接器可能不以相同的方式运行(并且 chrpath 可能是仅适用于 Linux 的工具)。
管理您的环境
管理每个应用程序LD_LIBRARY_PATH
设置的常见方法是使用包装器脚本(如 ewwhite 所建议的),或者使用类似环境模块项目。这可让您将环境变量设置(及更多内容)打包到不同的单元中,以便您执行以下操作:
module load myapplication
并妥善设置您的PATH
、LD_LIBRARY_PATH
和MANPATH
其他一切,以便访问我的应用程序。完成后,您可以:
module unload myapplication
撤消环境改变。
答案2
在我的背景下,通常的做法是使用包装器脚本来执行应用程序。在该包装器脚本中,将为特定应用程序设置 LD_LIBRARY_PATH。执行完成后,可以选择取消设置该变量。