一、Linux动态库路径
1 基础知识
变量是计算机系统用于保存可变值的数据类型,我们可以直接通过变量名称来提取到对应的变量值。
在Linux系统中,环境变量是用来定义系统运行环境的一些参数,比如每个用户不同的家目录(HOME)等。
值得一提的是,Linux 系统中环境变量的名称一般都是大写的,这是一种约定俗成的规范。
1.1 Linux环境变量详解
查看系统所有环境变量
env
查看单个环境变量值
echo $ENVNAME
# 例如,查看HOME
echo $HOME
设置环境变量的值
ENVNAME=value
使用 env 命令,我们可以查看当前系统所有的环境变量,使用 echo 命令,可以查看单个环境变量的值,直接使用 “环境变量名=值” 的形式即可以设置环境变量的值。
2 Linux动态库加载优先级
2.1 gcc编译程序时候查找动态库的顺序
-
gcc编译时参数
-L
指定的路径 -
环境变量
LIBRARY_PATH
-
/lib
-
/usr/lib
2.2 Linux程序运行时查找动态库的顺序
-
gcc 编译时指定的运行时库路径
-Wl,-rpath
-
环境变量
LIBRARY_PATH
-
ldconfig 缓存 /etc/ld.so.cache
-
/lib
-
/usr/lib
3 Linux程序运行动态库设定方法
3.1 -Wl,-rpath
- -Wl: 是编译器(gcc)选项,用于将后续的参数传递给传递给链接器(ld)。它允许你在编译和链接过程中向链接器传递额外的参数或选项,以控制链接的行为。这里就是传递
-rpath
。 - -Wl,-rpath:使用冒号(:)来分隔多个路径,例如
gcc -o test test.c -Wl,-rpath,/path1:/path2
- -L:是编译时动态库所在目录
3.2 环境变量LD_LIBRARY_PATH
# 多个路径需要用冒号隔开,$表示取环境变量LD_LIBRARY_PATH的值
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/your/path
如果想要每次打开shell窗口,都可以自动设定该环境变量,在文件 ~/.bashrc 最后一行添加以上内容
运行 source ~/.bashrc
使其生效
3.3 /etc/ld.so.conf
` ldconfig `是一个动态链接库管理命令。主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式 lib.so),进而创建出动态装入程序(ld.so)所需的连接和缓存文件(默认缓冲文件是 /etc/ld.so.cache)。
/etc/ld.so.conf 文件和 /etc/ld.so.conf.d 目录中指定的库文件
3.1 /etc/ld.so.conf添加
用sudo权限在/etc/ld.so.conf
文件最后新增一行动态库路径,比如写入/usr/local/lib
。然后命令行运行sudo ldconfig
。
3.2 /etc/ld.so.conf.d目录添加
lieryang@lieryang-B760M-AORUS-ELITE-AX:/etc$ cat ld.so.conf
include /etc/ld.so.conf.d/*.conf
发现只有在 ld.so.conf.d
文件夹内,以 .conf
结尾的文件也会包含到其中。
例如:
lieryang@lieryang-B760M-AORUS-ELITE-AX:/etc/ld.so.conf.d$ sudo touch test.conf
lieryang@lieryang-B760M-AORUS-ELITE-AX:/etc/ld.so.conf.d$ sudo echo /usr/local/mylib/lib >> test.conf
注意事项:
- 往/lib和/usr/lib里面添加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调用ldconfig,更新缓存文件。
- 以上两个目录以外添加东西,需要将目录/usr/local/mylib/lib添加到/etc/ld.so.conf,然后调用ldconfig,更新缓存文件。
4 问题总结
4.1 符号链接不能找到问题
lieryang@lieryang-B760M-AORUS-ELITE-AX:~$ sudo ldconfig
[sudo] password for lieryang:
/sbin/ldconfig.real: /lib/x86_64-linux-gnu/libavutil.so.56 is not a symbolic link
libavutil.so.56
应该是一个符号链接,但是 libavutil.so.56
是一个实体文件。
# 查看后发现 libavutil.so.56 是一个实体文件,貌似应该是 libavutil.so.56 是符号文件, libavutil.so是实体文件才正确(不过我们这里不这样修改)
lieryang@lieryang-B760M-AORUS-ELITE-AX:~$ ls -al /lib/x86_64-linux-gnu/libavutil.so*
lrwxrwxrwx 1 root root 15 10月 23 18:45 /lib/x86_64-linux-gnu/libavutil.so -> libavutil.so.56
-rwxr-xr-x 1 root root 1554824 10月 23 18:45 /lib/x86_64-linux-gnu/libavutil.so.56
-rw-r--r-- 1 root root 691088 5月 19 2022 /lib/x86_64-linux-gnu/libavutil.so.56.70.100
# 修改 libavutil.so.56 名称为 libavutil.56.so
lieryang@lieryang-B760M-AORUS-ELITE-AX:/lib/x86_64-linux-gnu$ sudo mv libavutil.so.56 libavutil.56.so
# 重新建立符号链接 libavutil.so.56 -> libavutil.56.so
lieryang@lieryang-B760M-AORUS-ELITE-AX:/lib/x86_64-linux-gnu$ sudo ln -s libavutil.56.so libavutil.so.56
不清楚为什么??? libavutil.so.56 必须是符号文件,哪里决定的??
4.2 如何查看链接器ld默认搜索路径
ld --verbose | grep SEARCH_DIR