# ldd/nm命令及ELF文件及LD_LIBRARY_PATH环境变量

# 命令介绍

lddlist dynamic dependencies,其作用是列出target的动态链接库目录RPATH

RPATH即硬编码在可执行文件或者动态库中的一个或多个路径,被动态链接加载器用来搜索依赖库。

如执行ldd libxx.so看到的如下信息,

libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff3ee589000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff3ee397000)

如果ldd查看到target中某个动态链接库为not found,

ldd test_cmake 
# linux-vdso.so.1 (0x00007ffe97ea8000)
# libhello-cmake.so => not found

说明目标文件中没有RPATH信息,这种情况有可能是编译时关闭了添加RPATH选项,如CMAKE中设置set(CMAKE_SKIP_RPATH TRUE)

可以设置LD_LIBRARY_PATH来指定,并在之后使用ldconfig使配置生效。

至于搜索路径,除了 RPATH,链接加载器在 Linux 中,还会有另外几个关键的路径,他们的搜索顺序如下:

  • RPATH搜索优先级别在LD_LIBRARY_PATH系统变量之前。
  • LD_LIBRARY_PATH:环境变量,也是一个或多个路径;
  • RUNPATH: 与 RPATH 一样,但是搜索顺序在 LD_LIBRARY_PATH 后面,只在比较新的系统中被支持;
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/xx/abx/libabx.so
sudo ldconfig

# nm命令

nm命令也可以获取库函数的信息;

nm命令可以列出一个函数库文件中的符号表,它对静态的库函数和共享的库函数都能起作用。

# ELF格式文件

ELF文件(Executable Linkable Format)是一种文件存储格式。Linux下的目标文件和可执行文件都按照该格式进行存储。

  • 可重定位目标文件包含二进制代码和数据,其形式可以和其他目标文件进行合并,创建一个可执行目标文件。例如.o文件
  • 可执行目标文件包含二进制代码和数据,可直接被加载器加载执行。例如编译好的可执行文件a.out
  • 共享对象文件,用于和其他共享目标文件或者可重定位文件一起生成ELF目标文件或者和执行文件一起创建进程映像,例如.so文件。

使用readelf命令可以查看节头表内容。