用于删除后缀开头的路径前缀

用于删除后缀开头的路径前缀

我有一个程序想要在我使用环境变量指定的目录的子目录中查找库文件。是否可以在我指定的目录中放置一个忽略正在附加的第一个子目录的路径?这就是我的意思。

我的文件夹结构

/usr/lib64/[All the library files]

程序看

$MAGICK_HOME/lib/[All the library files]

我可以在哪里操纵$MAGICK_HOME.

所以如果我设置MAGICK_HOME=/usr它会查看/usr/lib/[library files],这是错误的。如果我设置MAGICK_HOME=/usr/lib64它会看看/usr/lib/lib64/[library files]哪个也是错误的。

如果是相反的情况,我可以通过以 a 开头后缀来../从最外层目录返回,从而忽略前缀路径中指定的最后一个目录。我可以输入什么来MAGICK_HOME指定正确的目录?

答案1

以下是 3 种有趣的情况:

您的应用程序正在读取 的库/usr/lib64,但您希望它读取 的库$MAGICK_HOME/lib

如果您正在编译应用程序,您可以添加一些RPATH规则RUNPATH,以便二进制文件在$ORIGIN/../lib64.否则,您可以添加$MAGICK_HOME/lib$LD_LIBRARY_PATH启动二进制文件的 shell 脚本中,以便动态链接器在该路径中搜索二进制文件,或者您可以使用ldconfig将特定库添加到/etc/ld.so.cache


您的应用程序正在读取的库$MAGICK_HOME/lib而不是/usr/lib64

当 ld.so 动态链接时,它会搜索:

  • DT_RPATH在 ELF 二进制文件中编译的字段(如果DT_RUNPATH不存在)。这通常是绝对路径,或相对于二进制文件 ( ) 位置的路径$ORIGIN。我认为像这样的环境变量$MAGICK_HOME不会影响它。
  • $LD_LIBRARY_PATH环境变量(除非在安全执行模式下运行)
  • DT_RUNPATH在 ELF 二进制文件中编译的字段(类似于DT_RPATH上面)。
  • /etc/ld.so.cache,其中包含候选共享对象的编译列表。
  • /lib和的默认路径/usr/lib。在某些体系结构上,64 位共享对象的默认路径是/lib64/usr/lib64。如果二进制文件是通过-z nodeflib链接器选项链接的,则跳过此步骤。

由于/usr/lib64可能位于默认路径中,我怀疑该程序$LD_LIBRARY_PATH在启动时进行操作,或者用于在安装过程中ldconfig添加库/etc/ld.so.cache。这将导致$MAGICK_HOME/lib首先找到库。如果您可以阻止它执行这些操作,那么它应该回退到/usr/lib64.

您可以使用它readelf来查看它是否是针对特定DT_RPATH或编译的DT_RUNPATH,但我认为情况并非如此,因为听起来环境变量会影响链接,并且这些选项(AFAIK)不会受到环境的影响。


您的应用程序无法启动,因为它找不到安装的库/usr/lib64

如果问题不是它加载了错误的二进制文件,而是它没有加载任何二进制文件,那么可能是它/usr/lib64不在您的默认路径中。我们需要了解您的发行版和架构,以便在这种情况下提供进一步的帮助。

相关内容