咱們知道,GCC/G++提供了-L選項用於連接時指定要連接的庫的路徑,可是這個選項只限於編譯時,在運行時,可執行文件並未記住連接庫的路徑,所以在程序初始化的時候,動態加載程序會報告找不到動態庫錯誤。ios
示例代碼以下:c++
test.cc:spa
#include <iostream>orm
void dumpTest() {
std::cout << "This is dumpTest" << std::endl;
}
開發
main.cc:io
#include <iostream>編譯
extern void dumpTest();
int main() {
std::cout << "This is Linux platform" << std::endl;
dumpTest();form
return 0;
}
說明:test.cc編譯成 libtest.so,main.cc連接 libtest.so生成可執行文件main。test
問題:stream
使用以下命令編譯main,在運行時報告找不到 libtest.so:
g++ -L./yepanl -o main main.cc -ltest
運行結果以下:
$ ./main
./main: error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
解決辦法一:
設置運行時環境變量 LD_LIBRARY_PATH,這種狀況適用於嵌入式運行等環境:
export LD_LIBRARY_PATH=./yepanl:$LD_LIBRARY_PATH
解決辦法二:
編譯連接可執行文件時,增長 -Wl,--rpath=選項,連接器在可執行文件頭中記錄動態庫的路徑,動態加載器運行時讀取動態庫路徑,加載動態庫。這種狀況適用於主機開發運行環境:
g++ -L./yepanl -o main main.cc -ltest -Wl,--rpath=./yepanl
$ readelf -d main
Dynamic section at offset 0xdf8 contains 27 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libtest.so]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000f (RPATH) Library rpath: [./yepanl]
0x000000000000000c (INIT) 0x4007c8
0x000000000000000d (FINI) 0x400a74
0x0000000000000019 (INIT_ARRAY) 0x600dd8
0x000000000000001b (INIT_ARRAYSZ) 16 (bytes)
0x000000000000001a (FINI_ARRAY) 0x600de8
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x400298
0x0000000000000005 (STRTAB) 0x4004a8
0x0000000000000006 (SYMTAB) 0x4002e0
0x000000000000000a (STRSZ) 429 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x601000
0x0000000000000002 (PLTRELSZ) 216 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x4006f0
0x0000000000000007 (RELA) 0x4006c0
0x0000000000000008 (RELASZ) 48 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffe (VERNEED) 0x400680
0x000000006fffffff (VERNEEDNUM) 2
0x000000006ffffff0 (VERSYM) 0x400656
0x0000000000000000 (NULL) 0x0
總結:-L選項用於連接時搜索動態庫,-Wl,--rpath=用於運行時搜索動態庫。