rpath增添依賴庫搜尋路徑

查志強發表於2014-06-21

【原文:http://www.myexception.cn/other/681660.html

rpath新增依賴庫搜尋路徑

windows 下一個程式的dll搜尋路徑首先是程式目錄,然後是一些系統目錄。linux 下的可以通過設定 LD_LIBRARY_PATH 等方法來新增搜尋路徑,但是這些路徑是定死的,如果要實現程式目錄,就要使用連結時的rpath選項。rpath 適用於 elf 檔案,不適用 pe。

Linux 上動態庫搜尋順序:

Unless loading object has RUNPATH:
    RPATH of the loading object,
        then the RPATH of its loader (unless it has a RUNPATH), ...,
        until the end of the chain, which is either the executable
        or an object loaded by dlopen(loader 為可執行程式或被 dlopen 開啟的物件)
    Unless executable has RUNPATH:
        RPATH of the executable
LD_LIBRARY_PATH
RUNPATH of the loading object
ld.so.cache
default dirs


rpath 用法

ld: 
-rpath dir or --rpath=dir
為了相容其他 ELF 連結器,如果 -R 選項的值是個目錄而不是檔案,那麼此時相當與 -rpath
注:-R filename 與 --just-symbols=filename 等價
如果連結時沒使用 '-rpath' ,那麼如果定義了 LD_RUN_PATH 就會使用該值作為 rpath


ld 如果不是直接被呼叫的,而是是通過一個驅動程式如 gcc 呼叫,那麼的所有的連結選項都需要加上字首 "-Wl,", 選項和值之間用","隔開

所以gcc的rpath用法: 

-Wl,-rpath,dir

多個dir之間用冒號分隔: 

-Wl,-rpath,dir1:dir2:...:dirN


$ORIGING

代表程式目錄,需要加單引號,否則會被解釋為變數ORIGIN的值。這樣gcc的連結flags為
-Wl,-rpath,'$ORIGIN'

'-Wl,-rpath,$ORIGIN'

用 readelf 檢視編譯後的程式
readelf -d path
會發現多了類似與這麼一行
0x0000000f (RPATH)                      Library rpath: [$ORIGIN]

這樣,程式執行前會先搜尋程式所在路徑有沒有依賴的庫。


Makefile 中的寫法:

注意Makefile裡要用兩個$$,只用一個$會展開成變數值,$$相當與轉義成$
LFLAGS += '-Wl,-rpath,$$dir'


qmake 工程中的寫法:

QMAKE_LFLAGS += -Wl,-rpath,\'\$\$dir\'

QMAKE_RPATHDIR += :\'\$\$dir\' 
注意QMAKE_RPATHDIR最開始要加冒號,因為生成Makefile會自動在前面加上-Wl,-rpath,$$PWD


bash 裡執行 make 命令:

make LDFLAGS="'-Wl,-R,\$\$ORIGIN'"


其他有待調查的問題

1. ld -z -origin 或 g++ -Wl,-z,origin
不知道這個有什麼作用,文件裡一筆帶過沒看明白。readelf 看了下多了類似與如下的一行
0x6ffffffb (FLAGS_1)                    Flags: ORIGIN

2. macx
@executable_path : relative to the main executable
@loader_path : relative to the referring binary
@rpath : relative to any of a list of paths.
from qtcreator/src/rpath.pri:
    !isEmpty(TIGER_COMPAT_MODE) {
        QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../PlugIns/
    } else {
        QMAKE_LFLAGS_SONAME = -Wl,-install_name,@rpath/PlugIns/
        QMAKE_LFLAGS += -Wl,-rpath,@loader_path,-rpath,@executable_path
    }
使用 otool 檢視

3. clang
4. RUNPATH, DT_RUNPATH

參考文獻:

http://itee.uq.edu.au/~daniel/using_origin/
http://stackoverflow.com/questions/9263256/can-you-please-help-me-understand-how-mach-o-libraries-work-in-mac-os-x
http://itee.uq.edu.au/~daniel/using_origin/
http://stackoverflow.com/questions/6324131/rpath-origin-not-having-desired-effect
http://www.delorie.com/gnu/docs/binutils/ld_3.html
http://labs.qt.nokia.com/2011/10/28/rpath-and-runpath/
http://blog.csdn.net/dbzhang800/article/details/6918413  

相關文章