一、参考资料
error while loading shared libraries的解决方案
libascend_hal.so: cannot open shared object file:No such…解决办法-云社区-华为云 (huaweicloud.com)
二、相关介绍
1. -lxxx.so命名
`lxxx` means `lib + lib-name + .so`
lc means libc.so,
lltdl means libltdl.so,
lXtst means libXts.so
2. 查找 .so 文件
ld -lxxx --verbose
gcc -lxxx --verbose
locate libhdf5.so
/usr/bin/ld: cannot find -lhdf5
# 这表示找不到库文件 libhdf5.so
# 若是其它库文件,则是 cannot find -lxxx ,其中 xxx 是库文件的名字。
解释说明
-
-lxxx
表示lib + lib-name + .so
。例如,-lhdf5
表示libhdf5.so
。
3. 静态库与动态库
静态库 GCC 进行链接时,会把静态库中代码打包(复制)到可执行程序中,程序运行时,可执行文件里就包含了所有的代码,直接运行。
动态库 GCC 进行链接时,动态库的代码不会被打包到可执行程序中,只是打包一些有关于动态库的信息,在运行时才找到动态库文件位置,加载代码后才运行。
4. ldd指令
通过 ldd (list dynamic dependencies)
指令,检查动态库依赖关系。
5. 搜索动态库路径
当系统加载可执行代码时候,能够知道其所依赖库的名字,但是还需要知道绝对路径。此时就需要系统的动态载入器来获取该绝对路径。
对于ELF 格式的可执行程序,是由 ld-linux.so
来完成的,找到库文件后将其载入内存。它先后搜索的顺序是:
- elf文件的
DT_RPATH
段; - 环境变量
LD_LIBRARY_PATH
; -
/etc/ld.so.cache
文件列表; -
/lib
或/usr/lib
或/usr/local/lib
目录。
6. ld.so.conf配置文件
ld.so.conf
配置的作用是,将 /etc/ld.so.conf
列出的库文件路径缓存到 /etc/ld.so.cache
以供使用。当安装完一些库文件,或者在 /etc/ld.so.conf
配置文件中增加新的库文件搜索路径,运行一下ldconfig,使所有的库文件都被缓存到文件 /etc/ld.so.cache
中。如果没有做以上操作,可能会找不到刚安装的库。
可以通过以下指令,更新ld.so.conf
配置文件:
# 打开配置文件
sudo vi /etc/ld.so.conf
# 新增一行
/usr/local/lib
# 使配置生效
sudo ldconfig
# 查看配置
/sbin/ldconfig -v
三、问题描述
1. 情况一
/usr/bin/ld: cannot find -lxxx 的解决办法
make编译时,找不到 lxxx.so
动态库,导致报错。
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lltdl
/usr/bin/ld: cannot find -lXtst
2. 情况二
run运行可执行文件,找不到 .so
动态库,导致报错。
error while loading shared libraries: libXXXXXXX.so.1: cannot open shared object file: No such file or directory
libcal.so: cannot open shared object file: No file or directory
四、问题分析
1. 情况一
1.1 分析原因
默认情况下,编译器只会使用 /lib
和 /usr/lib
这两个目录下的库文件,通常通过源码包进行安装时,如果不指定 –prefix
,会将库安装在 /usr/local/lib
目录下;当运行程序需要链接动态库时,提示找不到相关的 .so
库,会报错。也就是说,/usr/local/lib
目录不在系统默认的库搜索目录中,需要将目录加进去。
1.2 解决办法
可以设定 LD_LIBRARY_PATH
环境变量,程序运行时会在此环境变量指定的文件夹下寻找动态链接库。
1.2.1 修改环境变量(永久有效)
其实,对于由普通用户自己编译生成的.so库文件,比较好的做法是将这些.so库文件的路径用export指令加入到~/.bashrc
中的LD_LIBRARY_PATH
变量中,LD_LIBRARY_PATH
是程序运行需要链接.so库时会去查找的一个目录,~/.bashrc
是登陆或打开shell时会读取的文件,这样,每次用户登录时,都会把这些.so库文件的路径写入LD_LIBRARY_PATH
,这样就可以正常地使用这些.so库文件了。
普通用户可直接修改~/.bashrc
或~/.bash_profile
,该修改仅对当前用户有效。
root用户可修改/etc/profile
,且对所有用户都有效。
以修改 ~/.bashrc
配置文件为例:
# 打开配置文件
vim ~/.bashrc
# 添加配置
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/hua/Myproject/1_basic/lib
# 若修改环境变量 LD_LIBRARY_PATH 不奏效,则修改变量 LIBRARY_PATH
export LIBRARY_PATH=$LIBRARY_PATH:/home/hua/Myproject/1_basic/lib
# 更新配置
source ~/.bashrc
1.2.2 修改环境变量(临时)
在终端使用export命令来配置环境变量,但仅限于当前终端;对于其他终端窗口则需要重新使用export命令才起作用。
export配置环境变量的格式为:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/hua/Myproject/1_basic/lib
1.2.3 运行成功
再次检查动态库依赖关系。
2. 情况二
2.1 分析原因
如果更新 ld.so.conf
配置文件,还是出现以上错误,那可能的原因是:当前用户没有读取库目录的权限。从其他主机上拷贝一些.so动态库,然后用root权限放到了/usr/local/lib
目录中(普通用户没有该目录的写权限),然后切换用户运行程序时,始终提示找不到.so库。用root权限增加到 /usr/local/lib
目录中的.so文件,对于普通用户而言,是没有访问权限的。所以,以普通用户运行程序,当需要链接.so库时,在/usr/local/lib
中是查找不到的。
2.2 解决办法
修改.so
文件的权限。
sudo chown yoyo:yoyo /usr/local/lib/libhdf5.so
3. 情况三
能找到 .so
文件。
3.1 查找 .so
文件
locate libiconv.so
$ locate libiconv.so
/home/user/anaconda3/lib/libiconv.so # <-- right here
/home/user/anaconda3/lib/libiconv.so.2
/home/user/anaconda3/lib/libiconv.so.2.5.1
/home/user/anaconda3/lib/preloadable_libiconv.so
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so.2
/home/user/anaconda3/pkgs/libiconv-1.14-0/lib/libiconv.so.2.5.1
3.2 创建软连接
Link it to the right place, usually it is /lib64
or /usr/lib64
。
$ sudo ln -s /home/user/anaconda3/lib/libiconv.so /usr/lib64/
4. 情况四
能找到 .so
文件,但不符合命名规则,创建软链接即可。例如:libasound.so.2
。
ln -s libasound.so.2 libasound.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.65.1 /usr/lib/libboost_filesystem.so
sudo ln -s /usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1 /usr/lib/libboost_system.so
5. 情况五
需要用户编译生成的 .so
文件。
When you compile your program you must supply the path to the library; in g++ use the -L
option:
编译c/c++程序,需要添加 -L
选项,才能生成 lib
链接库。文章来源:https://www.toymoban.com/news/detail-460680.html
# c程序
g++ -L/path/foo/bar myprogram.cc -lxxx -o myprogram
# c++程序
g++ -L/home/user/myDir myprogram.cpp -lxxx -lxxx -o myprogram
6. 情况六
如果找不到 .so
文件,则下载安装。文章来源地址https://www.toymoban.com/news/detail-460680.html
- google下载;
- 百度下载;
6.1 示例一
sudo apt-get install libfoo-dev
# 如果apt-get安装失败,先添加apt源再安装
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
sudo apt update
sudo apt install libjasper1 libjasper-dev
6.2 示例二
unable to locate libjasper-dev
# 解决办法
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
sudo apt update
sudo apt install libjasper1 libjasper-dev
到了这里,关于【超详细教程】解决libxxx.so: cannot open shared object file: No file or directory的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!