為什麼要關注動態庫路徑配置,是因為工作中遇到動態庫依賴其他動態庫,而其他動態庫又找不到的問題。
有一篇部落格寫的特別全:
linux 系統上有兩類根本不同的 linux 可執行程式。第一類是靜態鏈結的可執行程式。靜態可執行程式包含執行所需的所有函式 — 換句話說,它們是「完整的」。因為這一原因,靜態可執行程式不依賴任何外部庫就可以執行。
第二類是動態鏈結的可執行程式。
靜態可執行程式與動態可執行程式比較
我們可以用 ldd 命令來確定某一特定可執行程式是否為靜態鏈結的:
# ldd /sbin/sln
not a dynamic executable
「not a dynamic executable」是 ldd 說明 sln 是靜態鏈結的一種方式。現在,讓我們比較 sln 與其非靜態同類 ln 的大小:
# ls -l /bin/ln /sbin/sln
-rwxr-xr-x 1 root root 23000 jan 14 00:36 /bin/ln
-rwxr-xr-x 1 root root 381072 jan 14 00:31 /sbin/sln
如您所見,sln 的大小超過 ln 十倍。ln 比 sln 小這麼多是因為它是動態可執行程式。動態可執行程式是不完整的程式,它依靠外部共享庫來提供執行所需的許多函式。
動態鏈結相關性
要檢視 ln 依賴的所有共享庫的列表,可以使用 ldd 命令:
# ldd /bin/ln
libc.so.6 => /lib/libc.so.6 (0x40021000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
如您所見,ln 依賴外部共享庫 libc.so.6 和 ld-linux.so.2。通常,動態鏈結的程式比其靜態鏈結的等價程式小得多。不過,靜態鏈結的程式可以在某些低階維護任務中發揮作用。例如,sln 是修改位於 /lib 中的不同庫符號鏈結的極佳工具。但通常您會發現幾乎所有 linux 系統上的可執行程式都是某種動態鏈結的變體。
那麼,如果動態可執行程式不包含執行所需的所有函式,linux 的哪部分負責將這些程式和所有必需的共享庫一起裝入,以使它們能正確執行呢?答案是動態裝入器(dynamic loader),它實際上是您在 ln 的 ldd 清單中看到的作為共享庫相關性列出的 ld-linux.so.2 庫。動態裝入器負責裝入動態鏈結的可執行程式執行所需的共享庫。現在,讓我們迅速檢視一下動態裝入器如何在系統上找到適當的共享庫。
ld.so.conf
動態裝入器找到共享庫要依靠兩個檔案 — /etc/ld.so.conf 和 /etc/ld.so.cache。如果您對 /etc/ld.so.conf 檔案進行 cat 操作,您可能會看到乙個與下面類似的清單:
$ cat /etc/ld.so.conf
/usr/x11r6/lib
/usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.3
/usr/lib/mozilla
/usr/lib/qt-x11-2.3.1/lib
/usr/local/lib
ld.so.conf 檔案包含乙個所有目錄(/lib 和 /usr/lib 除外,它們會自動包含在其中)的清單,動態裝入器將在其中查詢共享庫。
ld.so.cache
但是在動態裝入器能「看到」這一資訊之前,必須將它轉換到 ld.so.cache 檔案中。可以通過執行 ldconfig 命令做到這一點:
# ldconfig
當 ldconfig 操作結束時,您會有乙個最新的 /etc/ld.so.cache 檔案,它反映您對 /etc/ld.so.conf 所做的更改。從這一刻起,動態裝入器在尋找共享庫時會檢視您在 /etc/ld.so.conf 中指定的所有新目錄。
ldconfig 技巧
要檢視 ldconfig 可以「看到」的所有共享庫,請輸入:
# ldconfig -p | less
還有另乙個方便的技巧可以用來配置共享庫路徑。有時候您希望告訴動態裝入器在嘗試任何 /etc/ld.so.conf 路徑以前先嘗試使用特定目錄中的共享庫。在您執行的較舊的應用程式不能與當前安裝的庫版本一起工作的情況下,這會比較方便。
ld_library_path
要指示動態裝入器首先檢查某個目錄,請將 ld_library_path 變數設定成您希望搜尋的目錄。多個路徑之間用冒號分隔;例如:
# export ld_library_path="/usr/lib/old:/opt/lib"
匯出 ld_library_path 後,如有可能,所有從當前 shell 啟動的可執行程式都將使用 /usr/lib/old 或 /opt/lib 中的庫,如果仍不能滿足一些共享庫相關性要求,則轉回到 /etc/ld.so.conf 中指定的庫。
Linux配置動態庫路徑的方法
解決方案 使用ld library path環境變數來配置,具體操作見案例。ld library path是linux環境變數名,該環境變數主要用於指定查詢共享庫 動態鏈結庫 時除了預設路徑之外的其他路徑。設定完成後,動態鏈結器會優先在該變數設定的路徑中查詢,若未找到則在標準庫路徑 lib和 usr...
linux指定動態庫路徑
通常有兩種方法 1.把動態庫放到系統庫或者在系統庫中做乙個鏈結,這樣編譯和執行都會去系統庫找。這樣容易引起系統庫混亂。2.export ld library path 指定庫搜尋路徑,但是這樣登出再登陸就沒了。還有第三種方法,編譯時使用 wl,rpath,wl,路徑 這樣就能把路徑編譯到可執行檔案裡...
linux 動態庫路徑查詢
linux 執行的時候,是如何管理共享庫 so 的?在 linux 下面,共享庫的尋找和載入是由 lib ld.so實現的。ld.so 在標準路經 lib,usr lib 中尋找應用程式用到的共享庫。但是,如果需要用到的共享庫在非標準路經,ld.so 怎麼找到它呢?目前,linux 通用的做法是將非...