可执行文件在运行时在哪里寻找共享对象?

可执行文件在运行时在哪里寻找共享对象?

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

例如,我的应用程序a.out调用库中定义的函数lib.so。编译后,我移动lib.so到我的$HOME.

我怎么知道a.out去那里寻找它?

答案1

共享库指南解释了所涉及的大部分机制,并且动态加载器手册更详细的内容。每个 UNIX 变体都有自己的方式,但大多数都使用相同的可执行格式(极低频)并有类似的动态链接器1(源自 Solaris)。下面我将重点总结 Linux 上的常见行为;检查您的系统手册以了解完整的情况。

(术语说明:系统中加载共享库的部分通常被称为“动态链接器”,但有时更准确地说是“动态加载器”。“动态链接器”也可以指编译时为动态加载器生成指令的工具一个程序,或者编译时工具和运行时加载器的组合。在这个答案中,“链接器”指的是运行时部分。)

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

  • 环境变量中列出的目录LD_LIBRARY_PATHDYLD_LIBRARY_PATH在 OSX 上);
  • 可执行文件中列出的目录路径;
  • 系统搜索路径上的目录,(至少在 Linux 上)由/etc/ld.so.confplus/lib和中的条目组成/usr/lib

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

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

答案2

在 Linux 中,该行为在ld(1)手册页中有明确说明

       The linker uses the following search paths to locate required
       shared libraries:

       1.  Any directories specified by -rpath-link options.

       2.  Any directories specified by -rpath options.  The difference
           between -rpath and -rpath-link is that directories specified by
           -rpath options are included in the executable and used at
           runtime, whereas the -rpath-link option is only effective at
           link time. Searching -rpath in this way is only supported by
           native linkers and cross linkers which have been configured
           with the --with-sysroot option.

       3.  On an ELF system, for native linkers, if the -rpath and
           -rpath-link options were not used, search the contents of the
           environment variable "LD_RUN_PATH".

       4.  On SunOS, if the -rpath option was not used, search any
           directories specified using -L options.

       5.  For a native linker, the search the contents of the environment
           variable "LD_LIBRARY_PATH".

       6.  For a native ELF linker, the directories in "DT_RUNPATH" or
           "DT_RPATH" of a shared library are searched for shared
           libraries needed by it. The "DT_RPATH" entries are ignored if
           "DT_RUNPATH" entries exist.

       7.  The default directories, normally /lib and /usr/lib.

       8.  For a native linker on an ELF system, if the file
           /etc/ld.so.conf exists, the list of directories found in that
           file.

       If the required shared library is not found, the linker will issue
       a warning and continue with the link.

答案3

我很确定这里的答案是ldconfig

ldconfig 创建指向在命令行指定的目录、文件 /etc/ld.so.conf 以及受信任目录(/lib 和 /usr/lib)中找到的最新共享库的必要链接和缓存。该缓存由运行时链接器 ld.so 或 ld-linux.so 使用。 ldconfig 在确定应更新哪些版本的链接时会检查它遇到的库的标头和文件名。

http://linux.die.net/man/8/ldconfig

答案4

对于正在运行的应用程序,该文件/proc/1234/maps包含所有实际的动态链接库。

1234正在运行的可执行文件的 pid 在哪里。

Linux 遵循 LD_LIBRARY_PATH 和其他变量,正如 Gilles 在回答中指出的那样。

相关内容