GCC/G++选项 -Wl,--rpath=

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

相关文章
相关标签/搜索