GCC/G++選項 -Wl,--rpath= 原

    我們知道,GCC/G++提供了-L選項用於鏈接時指定要鏈接的庫的路徑,但是這個選項只限於編譯時,在運行時,可執行文件並未記住鏈接庫的路徑,因此在程序初始化的時候,動態加載程序會報告找不到動態庫錯誤。

    示例代碼如下:

    test.cc:

#include <iostream>

void dumpTest() {
    std::cout << "This is dumpTest" << std::endl;
}
 

    main.cc:

#include <iostream>

extern void dumpTest();
int main() {
    std::cout << "This is Linux platform" << std::endl;
    dumpTest();

    return 0;
}
    說明:test.cc編譯成 libtest.so,main.cc鏈接 libtest.so生成可執行文件main。

    問題:

        使用如下命令編譯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=用於運行時搜索動態庫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章