執行檔在執行時在哪裡尋找共享對象?
我了解如何在連結/編譯時定義包含共享對象。但是,我仍然想知道執行檔
*.so
在執行時如何查找共享對象(庫)。例如,我的應用
a.out
呼叫lib.so
庫中定義的函式。編譯後,我移動lib.so
到我的$HOME
.我怎麼能告訴
a.out
去那裡找呢?
共享庫 HOWTO解釋了所涉及的大部分機制,動態載入器手冊更詳細。每個 unix 變體都有自己的方式,但大多數使用相同的可執行格式 ( ELF ) 並具有相似的動態連結器¹(源自 Solaris)。下面我將以 Linux 為重點總結常見行為;檢查您的系統手冊以獲取完整的故事。
(術語說明:載入共享庫的系統部分通常稱為“動態連結器”,但有時更準確地說是“動態載入器”。“動態連結器”也可以指編譯時為動態載入器生成指令的工具一個程序,或者編譯時工具和執行時載入程序的組合。在這個答案中,“連結器”是指執行時部分。)
簡而言之,當它在尋找動態庫(
.so
文件)時,連結器會嘗試:
LD_LIBRARY_PATH
環境變數中列出的目錄(DYLD_LIBRARY_PATH
在 OSX 上);- 執行檔的rpath中列出的目錄;
- 系統搜尋路徑上的目錄,其中(至少在 Linux 上)由
/etc/ld.so.conf
plus/lib
和/usr/lib
.rpath 儲存在執行檔中(它是
DT_RPATH
orDT_RUNPATH
動態屬性)。它可以包含絕對路徑或以 開頭$ORIGIN
的路徑,以指示相對於執行檔位置的路徑(例如,如果執行檔在/opt/myapp/bin
其中且其 rpath 為,$ORIGIN/../lib:$ORIGIN/../plugins
則動態連結器將在/opt/myapp/lib
and中查找/opt/myapp/plugins
)。rpath 通常在編譯執行檔時確定,使用-rpath
選項ld
,但您可以在之後使用chrpath
.在您描述的場景中,如果您是應用程序的開發人員或打包人員並打算將其安裝在
…/bin
,…/lib
結構中,則使用-rpath='$ORIGIN/../lib'
. 如果您要在系統上安裝預建構的二進製文件,請將庫放在搜尋路徑上的目錄中(/usr/local/lib
如果您是系統管理員,否則是您添加到的目錄$LD_LIBRARY_PATH
),或者嘗試chrpath
.