叶子🍃
叶子🍃
发布于 2026-06-25 / 0 阅读
0

关于Linux的动态链接库

找库顺序

动态链接器 /lib64/ld-linux-x86-64.so.2 会以以下的顺序来从路径里找库:

  1. RPATH

  2. LD_LIBRARY_PATH

  3. RUNPATH(和RPATH互斥,如果有RUNPATH会忽略RPATH)

  4. /etc/ld.so.cache (包含系统默认目录中的所有.so的位置,为了加速)

  5. 系统默认路径(通常有/lib:/lib64:/usr/lib:/usr/lib64之类的)

如果先找到了库libsomelib.so,被加载之后,后续如果还有elf依赖libsomelib.so的话,就不会继续找,直接复用(也就是说即使libotherlib.so的信息无法直接推断出他依赖的libsomelib.so的位置,如果已经有人先加载了libsomelib.so,libotherlib.so也会加载成功)。

动态链接库自身会携 RPATHRUNPATH 两个信息,可以通过以下命令查询

readelf -d /path/to/lib.so

其中$ORIGIN代表/path/to也就是elf文件所在的目录。

可以通过patchelf来改变RPATH、RUNPATH字段:

patchelf --print-rpath /path/to/lib.so
patchelf --set-rpath "..." /path/to/lib.so

RPATH 和 RUNPATH

RUNPATH 是更新的一个字段,如果elf中同时有RPATH和RUNPATH,那么RPATH会被忽略。

RPATH如果存在并且有效的话,优先级会高于LD_LIBRARY_PATH

RPATH会链式传递,假设有依赖 liba.so -> libb.so -> libc.so,那么libb.so最终的 RPATH 会同时包括两个 .so 的 RPATH。但是 RUNPATH 不会,RUNPATH的设计逻辑就是每个.so只声明自己依赖的部分(并且应当不包括依赖项libc.so的依赖)。