动态链接库
一、/etc/ld.so.conf.d 的作用
- 动态库路径管理:系统会读取该目录下的
.conf文件,这些文件指定了动态链接库的额外搜索路径。 - 配置动态库缓存:在运行程序时,动态链接器会从这些路径中查找所需的库。
默认加载的路径(视系统配置而定):
/lib/usr/lib/usr/local/lib
通过 /etc/ld.so.conf.d,可以扩展默认路径。
二、动态库的加载顺序
以 Linux / glibc 的常见 ELF 程序为例,所需库名不含斜杠时,搜索顺序通常涉及:
- 存在
DT_RPATH且没有DT_RUNPATH时,使用DT_RPATH。 LD_LIBRARY_PATH;安全执行模式下可能被忽略。DT_RUNPATH,主要用于该对象直接依赖的库。/etc/ld.so.cache中记录的匹配项。- 系统默认库目录,具体路径与架构、系统构建有关。
依赖名称已经包含斜杠时会按相应路径处理,不能再套用这份搜索列表。动态链接器不是每次运行都重新解析 ld.so.conf.d;这些配置通常由 ldconfig 读入并更新缓存。
还要区分两个阶段:编译链接阶段由 -L、-l 等选项寻找输入库;程序启动时再由动态加载器寻找运行所需库。运行时缓存配置不能代替编译命令中的 -L。
三、/etc/ld.so.conf.d 的文件结构
该目录包含多个 .conf 文件,每个文件可以指定一组路径。例如:
# 查看 /etc/ld.so.conf.d 内容
ls /etc/ld.so.conf.d
输出示例:
glibc.conf
x86_64-linux-gnu.conf
local.conf
文件示例:
- /etc/ld.so.conf.d/local.conf:
/usr/local/lib /opt/custom/lib
这些路径会被动态链接器添加到库搜索路径中。
四、如何配置动态库路径
1. 添加自定义路径
假设有一个自定义动态库路径 /home/user/mylibs,以下是配置步骤:
- 创建配置文件:
添加如下内容:sudo nano /etc/ld.so.conf.d/mylibs.conf/home/user/mylibs - 更新动态库缓存:
sudo ldconfig - 验证是否生效: 查看是否包含新路径:
ldconfig -p | grep mylibs
2. 临时配置路径
如果只是临时测试动态库路径,可以使用 LD_LIBRARY_PATH 环境变量:
export LD_LIBRARY_PATH="/home/user/mylibs${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
./myprogram
注意:这种方法作用于当前终端及其子进程。上面的条件拼接避免在原变量为空时留下空路径段;空路径段可能把当前工作目录加入搜索。
五、ldconfig 的作用
ldconfig 是管理动态库缓存的工具,其作用包括:
- 扫描路径:读取
/etc/ld.so.conf;只有它通过include引入相应文件时,才会读取ld.so.conf.d中的配置。 - 更新缓存:生成
/etc/ld.so.cache文件,加速库的加载。
常用命令
- 更新缓存:
sudo ldconfig - 指定路径更新缓存:
sudo ldconfig /home/user/mylibs - 查看当前缓存的库:
ldconfig -p
六、动态库配置实例
1. 动态库开发
创建一个简单动态库:
// hello.c
#include <stdio.h>
void hello(void) {
printf("Hello, from dynamic library!\n");
}
编译成动态库:
gcc -fPIC -shared -o libhello.so hello.c
将动态库移动到 /opt/mylibs:
sudo mkdir -p /opt/mylibs
sudo cp libhello.so /opt/mylibs/
2. 配置加载路径
创建 /etc/ld.so.conf.d/mylibs.conf:
sudo nano /etc/ld.so.conf.d/mylibs.conf
内容:
/opt/mylibs
更新缓存:
sudo ldconfig
3. 使用动态库
编写一个测试程序:
// main.c
void hello(void);
int main(void) {
hello();
return 0;
}
编译并运行:
gcc -o main main.c -L/opt/mylibs -lhello
./main
输出:
Hello, from dynamic library!
七、排错方法
- 检查动态库是否存在:
ldconfig -p | grep libhello - 验证动态库路径是否正确:
ldd ./main - 动态库无法加载时:
- 检查是否添加了正确的路径到
/etc/ld.so.conf.d。 - 检查是否运行了
ldconfig。
- 检查是否添加了正确的路径到
这里的 -L/opt/mylibs 解决链接阶段查找 libhello.so,上文的 ldconfig 配置解决运行阶段查找;缺少其中一环可能分别出现 cannot find -lhello 或 error while loading shared libraries。只对可信的本地程序使用 ldd;检查不可信文件可先用 readelf -d 查看静态依赖信息。
评论将在接近此处时加载,也可点击立即加载。