Libraries

為什麼 Unix/Linux 系統不遍歷目錄,直到找到所需的連結庫版本?

  • April 9, 2019

我有一個名為“alpha”的二進制執行檔,它需要一個連結庫(libz.so.1.2.7),它位於/home/username/myproduct/lib/libz.so.1.2.7

在通過執行以下命令生成我的二進制執行檔之前,我將其導出到我的終端實例。

export LD_LIBRARY_PATH=/home/username/myproduct/lib/:$LD_LIBRARY_PATH

現在,當我生成另一個需要相同庫但版本不同的應用程序“bravo”時,即 (libz.so.1.2.8) 可用 /lib/x86_64-linux-gnu/libz.so.1.2.8,系統會拋出以下錯誤。

version `ZLIB_1.2.3.3' not found (required by /usr/lib/x86_64-linux-gnu/libxml2.so.2)

如果我取消設置LD_LIBRARY_PATH,“bravo”啟動正常。我了解上述行為是因為LD_LIBRARY_PATH在查找連結庫時優先於定義的目錄路徑/etc/ld.so.conf,因此發生了上述錯誤。我只是好奇為什麼UNIX / LINUX的開發人員沒有設計作業系統來根據層次結構搜尋其他目錄中的連結庫,如果庫的第一個實例是不同的版本。

簡單地說,UNIX/LINUX 系統遍歷一組目錄,直到找到所需的庫。但是,為什麼它在找到預期版本之前不做同樣的事情,而不是接受庫的第一個實例而不管其版本如何?

但是,為什麼它在找到預期版本之前不做同樣的事情,而不是接受庫的第一個實例而不管其版本如何?

確實如此,據它所知。zlib.so.1.2.7並且zlib.so.1.2.8兩者都有一個 soname zlib.so.1,所以你alphabravo二進製文件說他們需要zlib.so.1。動態載入器載入它找到的第一個匹配庫;它不知道版本 1.2.8 提供了bravo需要的附加符號。(這就是為什麼發行版會煞費苦心地指定額外的依賴資訊,例如zlib1g (>= 1.2.8)for bravo。)

您可能認為這應該很容易解決,但事實並非如此,尤其是因為二進製文件和庫將它們需要的符號與它們需要的庫分開列出,因此載入器無法檢查給定庫是否提供了所有符號需要它。可以以多種方式提供符號,並且在符號和提供它們的庫之間引入連結可能會破壞現有的二進製文件。符號插入還增加了樂趣,使事情複雜化(並使對安全敏感的開發人員大發雷霆)。

一些庫提供最終儲存在 中的版本資訊.gnu.version_r,並帶有指向提供庫的連結,這在這裡會有所幫助,但libz不是其中之一。

(鑑於 sonames,我希望您的alpha二進製文件可以正常工作zlib.so.1.2.8。)

引用自:https://unix.stackexchange.com/questions/511380