咱们知道,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=用于运行时搜索动态库。