linux 共享库目录,Linux共享库
共享庫
從文件結構上講,共享庫和共享對象沒什么區別,Linux下共享庫就是普通的ELF共享對象。由于共享對象可以被各個程序之間共享,所以它也就成為了庫的很好的存在形式,很多庫的開發者都以共享對象的形式讓程序來使用。
共享庫的版本
共享庫的兼容
我們知道,共享庫是在不斷更新的。但是這種更新也會導致接口的更改和刪除。這個時候,就可能導致依賴共享庫的程序無法正常運行。
一般來說,共享庫的更新是有兩種的:
兼容更新。所有的更新只是在原有的共享庫基礎上添加一些內容。
不兼容更新。更新會改變原有的接口。
注意!我在這里寫到的接口是指ABI而不是API。
導致ABI改變的行為
一般改變C語言的ABI有四種主要的行為:
導出函數的行為發生改變。也就是說調用這個函數以后產生的結果和以前的不一樣,對函數的執行邏輯進行了改變
導出函數被刪除。
導出數據的結構發生變化,比如共享庫定義的結構體變量的結構發生改變,即對導出函數的返回值,參數列表的刪除或者名稱的修改。
導出函數的接口發生變化。如函數返回值、參數被更改。
當然還有其他行為:
比如說不通版本的編譯器、操作系統和硬件平臺等。
如何保持ABI兼容
對于C++,ABI問題會更加的嚴重,因為有虛函數表,模板實例化,多重繼承等問題。
但是,一般來說,按照以下的規則編寫C++共享庫基本就可以保持ABI兼容。
不要在接口中使用虛函數,萬不得已要使用虛函數時,不要隨意刪除、添加或在子類中添加新的實現函數。
不要改變類中任何成員變量的位置和類型。
不要刪除非內嵌的public或protected成員函數。
不要將非內嵌的成員函數改成內嵌成員函數。
不要改變成員函數的訪問權限。
不要在接口中使用模板
不要改變接口的任何部分干脆不要使用C++作為共享庫接口。
共享庫版本命名
Linux規定共享庫的文件名規則必須如下:
libname.so.x.y.z
后面跟的三個數字組成了版本號。
“x”表示主版本號。
主版本號表示庫的重大升級,不同主版本號的庫之間是不兼容的。
“y”表示次版本號。
次版本號表示庫的增量升級,即增加了一些新的符號接口,且保持原來的符號不變。在主版本號相同的情況下,高的次版本號向后兼容低的次版本號的庫。
“z”表示發布版本號。
發布版本號表示庫的一些錯誤的修正、性能的改進等,并不添加任何新的接口,也不對某個接口進行更改。相同主版本號、次版本號的共享庫,不同發布版本號之間完全兼容。
程序如何獲取依賴共享庫信息
我們假定程序中有一個它所依賴的共享庫列表,其中每一項對于于它所依賴的一個共享庫。
SO-NAME
對于Linux來說,普遍會采用一個叫SO-NAME的命名機制來記錄共享庫的依賴關系。每個共享庫都有一個對應的SO-NAME。
SO-NAME即共享庫的文件名只保留主版本號。
如 libfoo.so.2.1.6 的SO-NAME就是 libfoo.so.2
顯然,我們可以得出SO-NAME相同的兩個共享庫,次版本號大的兼容次版本號小的。
SO-NAME的優勢
SO-NAME其實是一個軟鏈接。實際上這個軟鏈接會指向目錄中主版本號相同、次版本號和發布版本號最新的共享庫。
所以它的優勢在于:
不用更改程序,直接更改軟鏈接。
總之,SO-NAME表示一個庫的接口,接口不想后兼容,SO-NAME就會發生變化。
鏈接名
當我們在編譯器使用共享庫的時候,我們會使用更簡潔的方式。
比如需要鏈接一個libXXX.so.2.6.1,就只需要在shell腳本中輸入-lXXX就行
共享庫的系統路徑
FHS規定,一個系統中主要有兩個存放共享庫的位置:
/lib ,這個位置主要存放系統最關鍵和基礎的共享庫
/usr/lib 這個目錄下主要保存的是一些非系統運行時所需要的關鍵性的共享庫
/usr/local/lib,這個目錄用來存放一些跟操作系統本身并不十分相關的庫。
FHS,一個大多數開源操作系統都遵循的標準
共享庫的查找過程
在linux中,動態鏈接的ELF可執行文件在啟動時會同時啟動動態鏈接器/lib/ld-linux.so.X,程序所依賴的共享對象全部由動態鏈接器負責裝載和初始化。
任何一個動態鏈接的模塊所依賴的模塊路徑保存在dynamic段中,由DT_NEED類型的項表示。動態鏈接器對于模塊的查找有一定的規則:
如果DT-NEED里面保存的是絕對路徑,那么動態鏈接器就會按照這個路徑去查找。如果是相對路徑,那么動態鏈接器就會在/lib、/usr/lib和由/etc/ld.so.conf配置文件指定的目錄中查找共享庫。
但是!
每次都去找這個目錄是否是太過笨逼?
所以Linux中引入了一個叫ldconfig的小程序,它會把共享庫目錄下的各個共享庫創建、刪除或更新相應的SO-NAME,這樣每個共享庫的SO-NAME就能夠指向正確的文件共享庫;并且這個程序還會將這些SO-NAME收集起來,集中存放到/etc/ld.so.cache文件,并建立一個SO-NAME的緩存。
參考文獻
[1] 俞甲子 石凡 潘愛明.程序員的自我修養.電子工業出版社,2009.4.
總結
以上是生活随笔為你收集整理的linux 共享库目录,Linux共享库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mui HTML5plus 批量上传文件
- 下一篇: 超市进销存系统设计