GCC 链接 xxx:No such file or directory 及运行可执行文件 error while loading shared libraries: xxx.so 解决方案
關(guān)于 GCC 提示找不到指定庫(kù)文件的這個(gè)問(wèn)題,通常出現(xiàn)在以下 2 個(gè)場(chǎng)景中:
- 利用靜態(tài)庫(kù)或者動(dòng)態(tài)庫(kù)文件實(shí)現(xiàn)鏈接操作(生成可執(zhí)行文件)時(shí),·
GCC可能會(huì)提示xxx:No such file or directory(其中xxx表示查找失敗的靜態(tài)庫(kù)或者動(dòng)態(tài)庫(kù)); - 執(zhí)行借助動(dòng)態(tài)庫(kù)生成的可執(zhí)行文件時(shí),
GCC可能會(huì)提示./main.exe: error while loading shared libraries: xxx.so: cannot open shared object file: No such file or directory(其中xxx表示動(dòng)態(tài)庫(kù)的文件名)。
1. GCC生成可執(zhí)行文件時(shí)找不到庫(kù)文件
要想徹底解決這個(gè)問(wèn)題,讀者就必須先了解在生成可執(zhí)行文件時(shí),GCC 編譯器默認(rèn)的查找?guī)煳募穆窂健?/p>
程序鏈接階段指明所用庫(kù)文件的方式有 2 種。假設(shè)當(dāng)前 mian.cpp 文件需要借助 libmyfunction.a 才能完成鏈接,則完成鏈接操作的 gcc 指令有以下 2 種寫法:
wohu@ubuntu:~/cpp/src$ gcc -static main.c libmyfunction.a -o main.exe
wohu@ubuntu:~/cpp/src$ gcc -static main.c -lmyfunction -o main.exe
當(dāng)以第一種寫法完成鏈接操作時(shí),GCC 編譯器只會(huì)在當(dāng)前目錄中(這里為 demo 目錄)查找 libmyfunction.a 靜態(tài)鏈接庫(kù);反之,如果使用 -l(小寫的 L)選項(xiàng)指明了要查找的靜態(tài)庫(kù)的文件名,則 GCC 編譯器會(huì)按照如下順序,依次到指定目錄中查找所需庫(kù)文件:
- 如果
gcc指令使用-L選項(xiàng)指定了查找路徑,則GCC編譯器會(huì)優(yōu)先選擇去該路徑下查找所需要的庫(kù)文件; - 再到
Linux系統(tǒng)中LIBRARY_PATH環(huán)境變量指定的路徑中搜索需要的庫(kù)文件; - 最后到
GCC編譯器默認(rèn)的搜索路徑(比如/lib、/lib64、/usr/lib、/usr/lib64、/usr/local/lib、/usr/local/lib64等,不同系統(tǒng)環(huán)境略有差異)中查找。
如果讀者使用第一種方法完成鏈接操作,但 GCC 編譯器提示找不到所需庫(kù)文件,表明所用庫(kù)文件并未存儲(chǔ)在當(dāng)前路徑下,解決方案就是手動(dòng)找到庫(kù)文件并將其移至當(dāng)前路徑,然后重新執(zhí)行鏈接操作。
反之,如果讀者使用的是第二種方法,也遇到了 GCC 編譯器提示未找到所需庫(kù)文件,表明庫(kù)文件的存儲(chǔ)路徑不對(duì),解決方案有以下 3 種:
- 手動(dòng)找到該庫(kù)文件,并在
gcc指令中用-L選項(xiàng)明確指明其存儲(chǔ)路徑。比如libmyfunction.a靜態(tài)庫(kù)文件存儲(chǔ)在/usr目錄下,則完成鏈接操作的gcc指令應(yīng)為
gcc -static main.c -L/usr -lmymath -o main.exe
- 將庫(kù)文件的存儲(chǔ)路徑添加到
LIBRARY_PATH環(huán)境變量中。仍以庫(kù)文件存儲(chǔ)在/usr目錄下,則通過(guò)執(zhí)行
export LIBRARY_PATH=$LIBRARY_PATH:/usr
指令,即可將 /usr 目錄添加到該環(huán)境變量中(此方式僅在當(dāng)前命令行窗口中有效);
- 將庫(kù)文件移動(dòng)到
GCC編譯器默認(rèn)的搜索路徑中。
2. GCC運(yùn)行可執(zhí)行文件時(shí)找不到動(dòng)態(tài)庫(kù)文件
執(zhí)行已生成的可執(zhí)行文件時(shí),如果 GCC 編譯器提示找不到所需的庫(kù)文件,這意味著 GCC 編譯器無(wú)法找到支持可執(zhí)行文件運(yùn)行的某些動(dòng)態(tài)庫(kù)文件。
事實(shí)上,當(dāng) GCC 編譯器運(yùn)行可執(zhí)行文件時(shí),會(huì)按照如下的路徑順序搜索所需的動(dòng)態(tài)庫(kù)文件:
- 如果在生成可執(zhí)行文件時(shí),用戶使用了
-Wl,-rpath=dir(其中dir表示要查找的具體路徑,如果查找路徑有多個(gè),中間用:冒號(hào)分隔)選項(xiàng)指定動(dòng)態(tài)庫(kù)的搜索路徑,則運(yùn)行該文件時(shí)GCC會(huì)首先到指定的路徑中查找所需的庫(kù)文件; GCC編譯器會(huì)前往LD_LIBRARY_PATH環(huán)境變量指明的路徑中查找所需的動(dòng)態(tài)庫(kù)文件;GCC編譯器會(huì)前往/ect/ld.so.conf文件中指定的搜索路徑查找動(dòng)態(tài)庫(kù)文件;GCC編譯器會(huì)前往默認(rèn)的搜索路徑中(例如/lib、/lib64、/usr/lib、/usr/lib64等)中查找所需的動(dòng)態(tài)庫(kù)文件。
注意,可執(zhí)行文件的當(dāng)前存儲(chǔ)路徑,并不在默認(rèn)的搜索路徑范圍內(nèi),因此即便將動(dòng)態(tài)庫(kù)文件和可執(zhí)行文件放在同一目錄下,
GCC編譯器也可能提示“找不到動(dòng)態(tài)庫(kù)”。
因此,對(duì)于 GCC 運(yùn)行可執(zhí)行文件時(shí)提示找不到動(dòng)態(tài)庫(kù)文件的問(wèn)題,常用的解決方法是:
- 將動(dòng)態(tài)庫(kù)文件的存儲(chǔ)路徑,添加到
LD_LIBRARY_PATH環(huán)境變量中。假設(shè)動(dòng)態(tài)庫(kù)文件存儲(chǔ)在/usr目錄中,通知執(zhí)行
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr
指令,即可實(shí)現(xiàn)此目的(此方式僅在當(dāng)前命令行窗口中有效);
- 修改動(dòng)態(tài)庫(kù)文件的存儲(chǔ)路徑,即將其移動(dòng)至
GCC編譯器默認(rèn)的搜索路徑中; - 修改
~/.bashrc或~/.bash_profile文件,即在文件最后一行添加
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx
(xxx 為動(dòng)態(tài)庫(kù)文件的絕對(duì)存儲(chǔ)路徑)。保存之后,執(zhí)行 source bashrc 指令(此方式僅對(duì)當(dāng)前登陸用戶有效)。
值得一提的是,GCC 編譯器提供有 ldd 指令,借助該指令,我們可以明確知道某個(gè)可執(zhí)行文件需要哪些動(dòng)態(tài)庫(kù)文件做支撐、這些動(dòng)態(tài)庫(kù)文件是否已經(jīng)找到、各個(gè)動(dòng)態(tài)庫(kù)文件的具體存儲(chǔ)路徑等信息。
以前面示例為例,執(zhí)行如下 ldd 指令:
wohu@ubuntu:~/cpp/src$ ldd main.exe
linux-vdso.so.1 => (0x00007fff06fb3000)
libmymath.so => /lib64/libmymath.so (0x00007f65b2a62000)
libc.so.6 => /lib64/libc.so.6 (0x00000037e2c00000)
/lib64/ld-linux-x86-64.so.2 (0x00000037e2800000)
注意,如果某個(gè)動(dòng)態(tài)庫(kù)文件未找到,則 => 后面會(huì)顯示 not found,表明 GCC 編譯器無(wú)法找到該動(dòng)態(tài)庫(kù),此時(shí)該可執(zhí)行文件將無(wú)法執(zhí)行。
總結(jié)
以上是生活随笔為你收集整理的GCC 链接 xxx:No such file or directory 及运行可执行文件 error while loading shared libraries: xxx.so 解决方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2022-2028年中国复合软管行业市场
- 下一篇: 浅显易懂 Makefile 入门 (0