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