可执行文件在运行时查找共享对象的位置?

Modified on: Sat, 30 Jun 2018 10:51:00 +0800

我理解如何在链接/编译时定义包含共享对象。但是,我仍然想知道可执行文件在执行时如何查找共享对象(*.so库)。

例如,我的app a.out调用lib.so库中定义的函数。编译完成后,我将lib.so移动到$HOME中的新目录。

我如何告诉a.out去那里寻找它?

最佳答案

共享库HOWTO解释了所涉及的大部分机制,以及动态装载机手册详细介绍。每个unix变体都有自己的方式,但大多数使用相同的可执行格式(ELF)并具有类似的动态链接器(源自Solaris)。下面我将总结一下关注Linux的常见行为;查看系统手册以了解完整的故事。

简而言之,当它正在寻找动态库(.so文件)时,链接器会尝试:

  • LD_LIBRARY_PATH环境变量中列出的目录(OSX上的DYLD_LIBRARY_PATH);
  • 可执行文件的rpath中列出的目录;
  • 系统搜索路径上的
  • 目录(至少在Linux上)由/etc/ld.so.conf/lib/usr/lib

rpath存储在可执行文件中(它是DT_RPATHDT_RUNPATH动态属性)。它可以包含以$ORIGIN开头的绝对路径或路径,以指示相对于可执行文件位置的路径(例如,如果可执行文件位于/opt/myapp/bin中,它的rpath是$ORIGIN/../lib:$ORIGIN/../plugins然后动态链接器会查找/opt/myapp/lib/opt/myapp/plugins)。 rpath通常在编译可执行文件时确定,-rpath选项到ld,但你可以用chrpath

在您描述的场景中,如果您是应用程序的开发人员或打包者,并打算将其安装在…/bin…/lib中结构,然后链接-rpath='$ORIGIN/../lib'。如果要在系统上安装预构建的二进制文件,请将库放在搜索路径上的目录中(/usr/local/lib,如果您是系统管理员,否则是目录您添加到$LD_LIBRARY_PATH),或尝试chrpath

作者:Gilles

相关问答

添加新评论