Linux动态链接库查找顺序:
在Linux里,当一个c语言程序中调用其他动态链接库时候,程序查找所需库的位置顺序如下:
1、编译时指定的位置
2、LD_LIBRARY_PATH 指定的位置
3、ldconfig 指定的位置
4、/lib(Linux动态链接库常放的位置)
5、/usr/lib(Linux动态链接库常放的位置)
其实,写到这里就可以不写了,但我还是准备挨着挨着演示一波。
多图预警:
库文件准备:
测试程序准备:
考虑到尽量少依赖其它基础知识的情况下,这里就不使用makefile来执行程序。咱们一步一步编译。
先创建几个文件夹:
111 222 333
这三个文件夹的作用是分别测试查找顺序的1、2、3。
现在开始编译,
编译第一个库文件,并将这个库文件放入111
gcc -o libtes.so 1.c -shared // -o 编译输出文件名 -shared是生成链接库
mv libtes.so 111
gcc -o libtes.so 2.c -shared
mv libtes.so 222
gcc -o libtes.so 3.c -shared
mv libtes.so 333
编译第四个库文件并将这个文件放入/lib
gcc -o libtes.so 4.c -shared
mv libtes.so /lib
编译第五个库文件并将这个文件放入/usr/lib
gcc -o libtes.so 5.c -shared
mv libtes.so /usr/lib
编译测试程序:
gcc -o test test.c -L ./111 -ltes -Wl,-rpath,111
// 这条编译命令比较复杂:
//-L是指定查找目录
//-ltes,-l是命令,tes是值,比如咱们需要连接的库为libxxx.so,这里的值就应该设置为-lxxx
//-Wl,rpath,111 指运行时去./111目录下找链接库
基本设置:
设置export LD_LIBRARY_PATH=$(pwd)/222,即设置环境变量到当前目录下的222
设置echo $(pwd)/333 >> /etc/ld.so.conf
执行ldconfig命令
测试结果:
1、先查找指定目录111下的库,即:打印111111
也可以用readelf -d test查看字段rpath,看到程序编译时候指定的路径:
也可以使用ldd命令查看程序所需链接库和其存放路径:
2、删除111下的libtes.so,继续执行程序
3、删除222下的libtes.so,继续执行程序
4、删除333下的libtes.so,继续执行程序
5、删除/lib下的libtes.so,继续执行程序
总结,由上述实验可知,Linux中c语言查找动态链接库的过程是:
编译时指定连接路径--->环境变量LD_LIBRARY_PATH--->配置文件/etc/ld.so.conf--->/lib--->/usr/lib
没有评论