為什麼我不能安裝多個版本的共享庫?
在某些情況下,某個程序依賴於庫版本 xy 而另一個依賴於 xz,但據我所知,沒有包管理器允許我同時安裝 xy 和 xz 有時它們會允許兩個主要版本(例如qt4 和 qt5,可以同時安裝),但(似乎)從來沒有次要版本。
為什麼是這樣?如,阻止它的限制因素是什麼?我認為不允許使用這個看似有用的功能一定有充分的理由。例如,在載入共享對象時是否沒有一個欄位來指示要載入的版本,因此 Linux 無法知道如何決定載入哪個版本?還是真的沒有理由?就像所有次要版本都應該兼容還是什麼?
實際上,如果操作正確,您可以安裝多個版本的共享庫。
共享庫通常命名如下:
lib<name>.so.<api-version>.<minor>
接下來,有以下名稱的庫的符號連結:
lib<name>.so lib<name>.so.<api-version>
當開發人員連結庫以生成二進製文件時,
.so
連結器找到的是以文件名結尾的文件名。對於任何給定的情況,一次確實只能安裝一個,<name>
但這僅意味著開發人員不能同時針對庫的多個不同版本。對於包管理器,這個.so
符號連結是一個單獨的-dev
包的一部分,只有開發人員需要安裝。當連結器找到名稱以 結尾的文件
.so
並使用它時,它會在該庫中查找名為soname的欄位。soname 建議連結器將什麼文件名嵌入到生成的二進製文件中,從而在執行時尋找什麼文件名。soname 應該設置為lib<name>.so.<api-version>
.因此,在執行時,動態連結器將尋找
lib<name>.so.<api-version>
並使用它。目的是:
<minor>
升級不會更改庫的 API,當<minor>
升級到更高版本時,讓所有二進製文件升級到新版本是安全的。由於二進製文件都在尋找lib<name>.so.<api-version>
名稱下的庫,這是一個符號連結到最新安裝的lib<name>.so.<api-version>.<minor>
,它們得到了升級。<api-version>
升級會改變庫的 API,讓現有的二進制應用程序使用新版本是不安全的。在<api-version>
更改的情況下,由於這些應用程序正在尋找名稱lib<name>.so.<api-version>
但具有不同值的<api-version>
,它們將不會選擇新版本。包管理器通常不會在同一個發行版中打包同一個庫的多個版本,因為整個發行版,包括使用該庫的所有二進製文件,通常在發行之前編譯為使用每個庫的一致版本。釋放。確保所有內容都是一致的,並且分發中的所有內容都與其他所有內容兼容,這是分銷商工作量的重要組成部分。
但是,如果您已將系統從發行版的一個版本升級到另一個版本並且仍然有一些需要較舊庫版本的較舊軟體包,那麼您很容易最終得到多個版本的庫。例子:
- libmysqlclient16來自較舊的 Debian,包含
libmysqlclient.so.16.0.0
和 symlinklibmysqlclient.so.16
。- 來自目前 Debian 的libmysqlclient18,包含
libmysqlclient.so.18.0.0
和 symlinklibmysqlclient.so.18
。