编译时库查找路径
-L
指定动态库路径 ,类似于通过-I
指定头文件包含路径
-l
指定使用的库名,可以在系统默认库路径(/lib、/usr/lib、/usr/local/lib)或者-L
指定路径中查找
运行时库查找路径
- 动态库的查找顺序:
- 编译时使用
-Wl,-rpath
可以为目标程序添加的查找的路径 - 通过
LD_LIBRARY_PATH
环境变量指定的路径 - vim /etc/ld.so.conf 中定义的动态库默认路径,注意该文件修改后,需要使用
sudo ldconfig
让修改生效
可以使用ldd xxx
查看程序的动态库查找结果
修改ELF文件的查找路径
- 修改编译选项
编译的时候使用-Wl,-rpath
为目标程序添加的查找路径,实际上是在生成的ELF中添加了路径字段
根据Linux发行版不同,默认添加的路径字段可能是DT_RPATH
或者DT_RUNPATH
,两者区别是DT_RUNPATH
仅作用于直接依赖,而DT_RPATH
作用于全部依赖:
Using the directories specified in the DT_RUNPATH dynamic section attribute of the binary if present. Such directories are searched only to find those objects required by DT_NEEDED (direct dependencies) entries and do not apply to those objects’ children, which must themselves have their own DT_RUNPATH entries. This is unlike DT_RPATH, which is applied to searches for all children in the dependency tree.
链接时使用--enable-new-dtags
可以固定生成DT_RUNPATH
,使用--disable-new-dtags
可以固定生成DT_RPATH
。
- 使用patchelf修改
可以安装patchelf
可以修改ELF的DT_RPATH
或者DT_RUNPATH
,安装方法:
sudo apt install patchelf
使用方法:
patchelf --set-rpath $rpath
:设置ELF的DT_RUNPATH
patchelf --force-rpath --set-rpath $rpath
:设置ELF的DT_RPATH
patchelf --set-interpreter $interpreter
:设置ELF的动态加载器,通常用于修改ELF使用的libc
绝对和相对路径
当编译的时候,直接指定编译的动态库相对路径,如“./libScanAPI.so”,则程序编译的时候在当前路径查找库,运行的时候也会在当前目录加载
当指定完整路径如“/home/xxx/libScanAPI.so”,则用的是绝对路径查找