运行时链接程序在两个缺省位置中查找依赖项。在处理 32 位目标文件时,缺省位置为 /lib 和 /usr/lib。在处理 64 位目标文件时,缺省位置为 /lib/64 和 /usr/lib/64。指定为简单文件名的任何依赖项都使用这些缺省目录名称作为前缀。生成的路径名用于查找实际文件。
使用 ldd(1) 可以显示动态可执行文件或共享目标文件的依赖项。例如,文件 /usr/bin/cat 具有下列依赖项:
$ ldd /usr/bin/cat libc.so.1 => /lib/libc.so.1 libm.so.2 => /lib/libm.so.2
文件 /usr/bin/cat 具有依赖项文件 libc.so.1 和 libm.so.2,即需要这些文件。
可以使用 elfdump(1) 检查目标文件中记录的依赖项。使用此命令可以显示文件的 .dynamic 节,并查找具有 NEEDED 标记的项。在以下示例中,前面的 ldd(1) 示例中显示的依赖项 libm.so.2 没有记录在文件 /usr/bin/cat 中。ldd(1) 显示了指定文件的全部依赖项,而 libm.so.2 实际上是 /lib/libc.so.1 的依赖项。
$ elfdump -d /usr/bin/cat Dynamic Section: .dynamic: index tag value [0] NEEDED 0x211 libc.so.1 ...
在前面的 elfdump(1) 示例中,依赖项表示为简单文件名。也就是说,名称中没有 "/"。使用简单文件名要求运行时链接程序根据一组缺省搜索规则生成路径名。包含嵌入 "/" 的文件名均按原样使用。
记录简单文件名是记录依赖项的一种最灵活的标准机制。链接编辑器的 –h 选项记录依赖项中的简单名称。请参见命名约定和记录共享目标文件名称。
通常,依赖项分布在 /lib 及 /usr/lib 或 /lib/64 及 /usr/lib/64 以外的目录中。如果动态可执行文件或共享目标文件需要在其他目录中查找依赖项,则必须显式指示运行时链接程序搜索此目录。
通过在链接编辑目标文件过程中记录运行路径,可以基于每个目标文件指定其他搜索路径。有关记录此信息的详细信息,请参见运行时链接程序搜索的目录。
使用 elfdump(1) 可以显示运行路径记录。请参考包含 RUNPATH 标记的 .dynamic 项。在以下示例中,prog 具有 libfoo.so.1 的依赖项。运行时链接程序必须先搜索目录 /home/me/lib 和 /home/you/lib,然后在缺省位置中查找。
$ elfdump -d prog | egrep "NEEDED|RUNPATH" [1] NEEDED 0x4ce libfoo.so.1 [3] NEEDED 0x4f6 libc.so.1 [21] RUNPATH 0x210e /home/me/lib:/home/you/lib
添加运行时链接程序搜索路径的另一种方法是设置环境变量 LD_LIBRARY_PATH。可以将该环境变量(在进程启动时即时对其分析)设置为一组以冒号分隔的目录。运行时链接程序会先搜索这些目录,然后搜索指定的任何运行路径或缺省目录。
这些环境变量非常适合在调试时使用,如将应用程序强制绑定到局部依赖项。在以下示例中,前面示例中的文件 prog 将绑定到当前工作目录中的 libfoo.so.1。
$ LD_LIBRARY_PATH=. prog
尽管 LD_LIBRARY_PATH 作为一种影响运行时链接程序搜索路径的临时机制很有用,但强烈建议不要在生产软件中使用它。可引用此环境变量的所有动态可执行文件都将扩充其搜索路径。此扩充可能导致性能整体下降。另外,根据使用环境变量和运行时链接程序搜索的目录中的说明,LD_LIBRARY_PATH 还会影响链接编辑器。
环境搜索路径可能导致 64 位可执行文件搜索包含与要查找的名称匹配的 32 位库的路径。反之亦然。运行时链接程序会拒绝不匹配的 32 位库,并继续搜索有效的 64 位匹配项。如果未找到匹配项,则会生成一条错误消息。通过将 LD_DEBUG 环境变量设置为包含 files 标记,可以详细观察此拒绝。请参见调试功能。
$ LD_LIBRARY_PATH=/lib/64 LD_DEBUG=files /usr/bin/ls .... 00283: file=libc.so.1; needed by /usr/bin/ls 00283: 00283: file=/lib/64/libc.so.1 rejected: ELF class mismatch: 32–bit/64–bit 00283: 00283: file=/lib/libc.so.1 [ ELF ]; generating link map 00283: dynamic: 0xef631180 base: 0xef580000 size: 0xb8000 00283: entry: 0xef5a1240 phdr: 0xef580034 phnum: 3 00283: lmid: 0x0 00283: 00283: file=/lib/libc.so.1; analyzing [ RTLD_GLOBAL RTLD_LAZY ] ....
如果无法找到某个依赖项,ldd(1) 将指出无法找到该目标文件。如果尝试执行应用程序,则会导致运行时链接程序生成相应的错误消息:
$ ldd prog libfoo.so.1 => (file not found) libc.so.1 => /lib/libc.so.1 libm.so.2 => /lib/libm.so.2 $ prog ld.so.1: prog: fatal: libfoo.so.1: open failed: No such file or directory