因此,我正在從事的專案使用非系統目錄來保存程式碼使用的一些 DLL。我不想將它們放在系統目錄中,因此可執行檔設定了一個 rpath 來尋找 DLL。然而,隨著越來越多的程式庫被添加,現在有 DLL 依賴該目錄中的其他 DLL。
這些程式庫無法找到它們所依賴的 DLL,因為它們不位於連結器正在尋找的目錄中,例如係統目錄。
有沒有辦法讓 DLL 搜尋這個特定的非系統目錄?例如rpath?圖書館是如何做到這一點的?該專案使用的建置系統是 CMake(如果這有助於回答)。
這個答案不起作用,因為庫中沒有 rPath 標籤:https://unix.stackexchange.com/a/272286/4193
我考慮過使用LD_LIBRARY_PATH
, 這很有效,但打字很煩人,而且讓其他人使用該應用程式也不是那麼好。如果有辦法將rPath
標籤新增到庫中,那將是最好的選擇。
感謝指向以前的相關問題和答案。
答案1
有動態連結函式庫的rpath嗎?
就在這裡。您可以使用-Wl,-rpath
ELF 共享對象,就像使用 ELF 可執行檔一樣。克隆我提出的小例子
這裡:
git clone https://gist.github.com/ardrabczyk/6aeb8545c9b754d6b15be390af4bdff0
運行make
編譯。檢查main
ELF 可執行檔需要哪些函式庫:
$ readelf -d ./main
Dynamic section at offset 0xe30 contains 22 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libtwo.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000f (RPATH) Library rpath: [.]
(...)
並檢查需要哪些函式庫libtwo.so
:
$ readelf -d ./libtwo.so
Dynamic section at offset 0xe38 contains 22 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libone.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000f (RPATH) Library rpath: [libs]
(...)
正如您所看到的,兩者main
都libtwo.so
需要一些共享對象,並且都設定了 rpath。您不需要設定 LD_LIBRARY_PATH 來執行 ./main:
$ ./main
I'm in bar()
.
main 將始終在目前目錄中尋找其 libtwo.so 依賴項,而 libtwo.so 將始終在libs
目錄中尋找其 libone.so 依賴項。如果libs
缺少 ./main 將不會啟動:
$ mv libs libs.bak
$ ./main
./main: error while loading shared libraries: libone.so: cannot open shared object file: No such file or directory
恢復它:
$ mv libs.bak libs
$ ./main
I'm in bar()
答案2
既然您不想將其視為系統的一部分,那就按原樣使用它;用戶應用程式!
如果您添加~/.local/lib/
到您的LD_LIBRARY_PATH
,您可以將所有內容放在那裡。只需在~/.local/
類似下創建部分FHS結構垃圾桶,ETC,庫和分享。這樣您就不需要使用前面的環境變數來呼叫程式。所有其他系統只需要將此目錄附加到其庫路徑環境變數中。非常整潔和unixish。
如果你也拒絕這個解決方案,那就只剩下一種可能性了。您可以使用每個系統都期望的固定路徑,也可以使用包含路徑且也是期望的環境變數。