一、參考資料
error while loading shared libraries的解決方案
libascend_hal.so: cannot open shared object file:No such…解決辦法-云社區(qū)-華為云 (huaweicloud.com)
二、相關(guān)介紹
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
# 這表示找不到庫(kù)文件 libhdf5.so
# 若是其它庫(kù)文件,則是 cannot find -lxxx ,其中 xxx 是庫(kù)文件的名字。
解釋說明
-
-lxxx
表示lib + lib-name + .so
。例如,-lhdf5
表示libhdf5.so
。
3. 靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)
靜態(tài)庫(kù) GCC 進(jìn)行鏈接時(shí),會(huì)把靜態(tài)庫(kù)中代碼打包(復(fù)制)到可執(zhí)行程序中,程序運(yùn)行時(shí),可執(zhí)行文件里就包含了所有的代碼,直接運(yùn)行。
動(dòng)態(tài)庫(kù) GCC 進(jìn)行鏈接時(shí),動(dòng)態(tài)庫(kù)的代碼不會(huì)被打包到可執(zhí)行程序中,只是打包一些有關(guān)于動(dòng)態(tài)庫(kù)的信息,在運(yùn)行時(shí)才找到動(dòng)態(tài)庫(kù)文件位置,加載代碼后才運(yùn)行。
4. ldd指令
通過 ldd (list dynamic dependencies)
指令,檢查動(dòng)態(tài)庫(kù)依賴關(guān)系。
5. 搜索動(dòng)態(tài)庫(kù)路徑
當(dāng)系統(tǒng)加載可執(zhí)行代碼時(shí)候,能夠知道其所依賴庫(kù)的名字,但是還需要知道絕對(duì)路徑。此時(shí)就需要系統(tǒng)的動(dòng)態(tài)載入器來獲取該絕對(duì)路徑。
對(duì)于ELF 格式的可執(zhí)行程序,是由 ld-linux.so
來完成的,找到庫(kù)文件后將其載入內(nèi)存。它先后搜索的順序是:
- elf文件的
DT_RPATH
段; - 環(huán)境變量
LD_LIBRARY_PATH
; -
/etc/ld.so.cache
文件列表; -
/lib
或/usr/lib
或/usr/local/lib
目錄。
6. ld.so.conf配置文件
ld.so.conf
配置的作用是,將 /etc/ld.so.conf
列出的庫(kù)文件路徑緩存到 /etc/ld.so.cache
以供使用。當(dāng)安裝完一些庫(kù)文件,或者在 /etc/ld.so.conf
配置文件中增加新的庫(kù)文件搜索路徑,運(yùn)行一下ldconfig,使所有的庫(kù)文件都被緩存到文件 /etc/ld.so.cache
中。如果沒有做以上操作,可能會(huì)找不到剛安裝的庫(kù)。
可以通過以下指令,更新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編譯時(shí),找不到 lxxx.so
動(dòng)態(tài)庫(kù),導(dǎo)致報(bào)錯(cuò)。
/usr/bin/ld: cannot find -lc
/usr/bin/ld: cannot find -lltdl
/usr/bin/ld: cannot find -lXtst
2. 情況二
run運(yùn)行可執(zhí)行文件,找不到 .so
動(dòng)態(tài)庫(kù),導(dǎo)致報(bào)錯(cuò)。
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 分析原因
默認(rèn)情況下,編譯器只會(huì)使用 /lib
和 /usr/lib
這兩個(gè)目錄下的庫(kù)文件,通常通過源碼包進(jìn)行安裝時(shí),如果不指定 –prefix
,會(huì)將庫(kù)安裝在 /usr/local/lib
目錄下;當(dāng)運(yùn)行程序需要鏈接動(dòng)態(tài)庫(kù)時(shí),提示找不到相關(guān)的 .so
庫(kù),會(huì)報(bào)錯(cuò)。也就是說,/usr/local/lib
目錄不在系統(tǒng)默認(rèn)的庫(kù)搜索目錄中,需要將目錄加進(jìn)去。
1.2 解決辦法
可以設(shè)定 LD_LIBRARY_PATH
環(huán)境變量,程序運(yùn)行時(shí)會(huì)在此環(huán)境變量指定的文件夾下尋找動(dòng)態(tài)鏈接庫(kù)。
1.2.1 修改環(huán)境變量(永久有效)
其實(shí),對(duì)于由普通用戶自己編譯生成的.so庫(kù)文件,比較好的做法是將這些.so庫(kù)文件的路徑用export指令加入到~/.bashrc
中的LD_LIBRARY_PATH
變量中,LD_LIBRARY_PATH
是程序運(yùn)行需要鏈接.so庫(kù)時(shí)會(huì)去查找的一個(gè)目錄,~/.bashrc
是登陸或打開shell時(shí)會(huì)讀取的文件,這樣,每次用戶登錄時(shí),都會(huì)把這些.so庫(kù)文件的路徑寫入LD_LIBRARY_PATH
,這樣就可以正常地使用這些.so庫(kù)文件了。
普通用戶可直接修改~/.bashrc
或~/.bash_profile
,該修改僅對(duì)當(dāng)前用戶有效。
root用戶可修改/etc/profile
,且對(duì)所有用戶都有效。
以修改 ~/.bashrc
配置文件為例:
# 打開配置文件
vim ~/.bashrc
# 添加配置
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/hua/Myproject/1_basic/lib
# 若修改環(huán)境變量 LD_LIBRARY_PATH 不奏效,則修改變量 LIBRARY_PATH
export LIBRARY_PATH=$LIBRARY_PATH:/home/hua/Myproject/1_basic/lib
# 更新配置
source ~/.bashrc
1.2.2 修改環(huán)境變量(臨時(shí))
在終端使用export命令來配置環(huán)境變量,但僅限于當(dāng)前終端;對(duì)于其他終端窗口則需要重新使用export命令才起作用。
export配置環(huán)境變量的格式為:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/hua/Myproject/1_basic/lib
1.2.3 運(yùn)行成功
再次檢查動(dòng)態(tài)庫(kù)依賴關(guān)系。
2. 情況二
2.1 分析原因
如果更新 ld.so.conf
配置文件,還是出現(xiàn)以上錯(cuò)誤,那可能的原因是:當(dāng)前用戶沒有讀取庫(kù)目錄的權(quán)限。從其他主機(jī)上拷貝一些.so動(dòng)態(tài)庫(kù),然后用root權(quán)限放到了/usr/local/lib
目錄中(普通用戶沒有該目錄的寫權(quán)限),然后切換用戶運(yùn)行程序時(shí),始終提示找不到.so庫(kù)。用root權(quán)限增加到 /usr/local/lib
目錄中的.so文件,對(duì)于普通用戶而言,是沒有訪問權(quán)限的。所以,以普通用戶運(yùn)行程序,當(dāng)需要鏈接.so庫(kù)時(shí),在/usr/local/lib
中是查找不到的。
2.2 解決辦法
修改.so
文件的權(quán)限。
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 創(chuàng)建軟連接
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
文件,但不符合命名規(guī)則,創(chuàng)建軟鏈接即可。例如: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
選項(xiàng),才能生成 lib
鏈接庫(kù)。文章來源:http://www.zghlxwxcb.cn/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
文件,則下載安裝。文章來源地址http://www.zghlxwxcb.cn/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
到了這里,關(guān)于【超詳細(xì)教程】解決libxxx.so: cannot open shared object file: No file or directory的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!