動態連接庫(轉載)

Linux 系統上有兩類根本不一樣的 Linux 可執行程序。第一類是靜態連接的可執行程序。靜態可執行程序包含執行所需的全部函數 — 換句話說,它們是「完整的」。由於這一緣由,靜態可執行程序不依賴任何外部庫就能夠運行。linux


第二類是動態連接的可執行程序。
shell

  靜態可執行程序與動態可執行程序比較

咱們能夠用 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 小這麼可能是由於它是動態可執行程序。動態可執行程序是不完整的程序,它依靠外部共享庫來提供運行所需的許多函數。less

  動態連接相關性函數

  要查看 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 系統上的可執行程序都是某種動態連接的變體。qt

  動態裝入器table

  那麼,若是動態可執行程序不包含運行所需的全部函數,Linux 的哪部分負責將這些程序和全部必需的共享庫一塊兒裝入,以使它們能正確執行呢?答案是動態裝入器(dynamic loader),它其實是您在 ln 的 ldd 清單中看到的做爲共享庫相關性列出的 ld-linux.so.2 庫。動態裝入器負責裝入動態連接的可執行程序運行所需的共享庫。如今,讓咱們迅速查看一下動態裝入器如何在系統上找到適當的共享庫。變量

  ld.so.confgcc

  動態裝入器找到共享庫要依靠兩個文件 — /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 中指定的庫。

相關文章
相關標籤/搜索