Linux動態鏈接庫.so文件的命名及用途總結


[轉]https://blog.csdn.net/zhanglianpin/article/details/50491958

我們在linux下開發項目,有時會對外提供動態庫,像***.so.1.0.0這樣子的文件,另外提供相應的頭文件。用戶拿到動態庫和頭文件說明,就可以使用動態庫里的function。

那隨之而來的一個問題是,動態庫的升級問題,我們的動態庫更改了一個bug,升級了一個版本,那使用我們動態庫的應用程序需要重新編譯嗎?運行時會產生異常嗎?linux下是怎么規范這些內容的吶?

大家一定聽說過windows下的dll hell。

Linux中的.so文件 是動態鏈接的產物 
共享庫理解為提供各種功能函數的集合,對外提供標准的接口
Linux中命名系統中共享庫的規則

主版本號:不同的版本號之間不兼容
次版本號:增量升級 向后兼容
發行版本號:對應次版本的錯誤修正和性能提升,不影響兼容性

下面說說linux下動態庫的命名規范。

 

為方便管理依賴關系,創建或部署共享庫時,必須遵循統一約定的規則才行,其中包括動態庫的命名規則及其部署方式。

共享庫命名約定


1) 每個動態庫有一個包含了真正的庫代碼的文件名,通常被稱為庫的 realname ,命名格式通常為

libxxx.so.x.y.z,其中so后綴中的x為主版本號,y為副版本號,z為發行版本號。例如,我的linux系統機器上zlib共享庫的realname為     libz.so.1.2.8,這個文件是含有可執行的二進制代碼的。

2) 每個動態庫都有一個以"lib"為前綴且以".so.x"為結尾的被稱為 soname

 

的特定名稱,其中x為主版本號,soname命名格式通常為libxxx.so.x。例如,我的linux系統機器上zlib共享庫的soname為libz.so.1。這個soname包含了動態庫的主版本號,這個doname一般會包含在庫代碼的頭文件中,這個可以使用 readelf -d 讀取出來,使用這個動態庫的程序的二進制ELF的頭文件中包含有這個動態庫的soname。程序運行時會按照這個名稱去找真正的庫文件。

3) 此外,編譯鏈依賴了共享庫的應用模塊時,鏈接器只認不帶任何版本號的共享庫名, 可以將庫名稱作" linker name。

例如,我的linux系統機器上zlib共享庫的linkername為libz.so。也即,鏈接使用了動態庫的程序時查找的動態庫名稱。例如:gcc -o test test.o -lz , 鏈接時就會找libz.so 。若沒有這個文件,鏈接器就報錯。

下面的內容轉自:http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

以實際例子的形式,詳細地闡述了realname soname linkername 之間的關系。

 

添加動態鏈接庫路徑

 

1. 連接和運行時庫文件搜索路徑到設置

庫文件在連接(靜態庫和共享庫)和運行(僅限於使用共享庫的程序)時被使用,其搜索路徑是在系統中進行設置的。一般 Linux 系統把 /lib 和 /usr/lib 兩個目錄作為默認的庫搜索路徑,所以使用這兩個目錄中的庫時不需要進行設置搜索路徑即可直接使用。對於處於默認庫搜索路徑之外的庫,需要將庫的位置添加到庫的搜索路徑之中。設置庫文件的搜索路徑有下列兩種方式,可任選其一使用:

 

(1). 在 /etc/ld.so.conf 文件中添加庫的搜索路徑。(或者在/etc/ld.so.conf.d 下新建一個.conf文件,將搜索路徑一行一個加入-junziyang)

將自己可能存放庫文件的路徑都加入到/etc /ld.so.conf中是明智的選擇添加方法也極其簡單,將庫文件的絕對路徑直接寫進去就OK了,一行一個。例如:

1
2
3
/usr/X11R6/lib
/usr/local/lib
/opt/lib

  需要注意的是:這種搜索路徑的設置方式對於程序連接時的庫(包括共享庫和靜態庫)的定位已經足夠了,但是對於使用了共享庫的程序的執行還是不夠的。這是因為為了加快程序執行時對共享庫的定位速度,避免使用搜索路徑查找共享庫的低效率,所以是直接讀取庫列表文件 /etc/ld.so.cache 從中進行搜索的。/etc/ld.so.cache 是一個非文本的數據文件,不能直接編輯,它是根據 /etc/ld.so.conf 中設置的搜索路徑由 /sbin/ldconfig 命令將這些搜索路徑下的共享庫文件集中在一起而生成的(ldconfig 命令要以 root 權限執行)。

 因此,為了保證程序執行時對庫的定位,在 /etc/ld.so.conf 中進行了庫搜索路徑的設置之后,還必須要運行 /sbin/ldconfig 命令更新 /etc/ld.so.cache 文件之后才可以。ldconfig ,簡單的說,它的作用就是將/etc/ld.so.conf列出的路徑下的庫文件緩存到/etc/ld.so.cache 以供使用。因此當安裝完一些庫文件,(例如剛安裝好glib),或者修改ld.so.conf增加新的庫路徑后,需要運行一下 /sbin/ldconfig使所有的庫文件都被緩存到ld.so.cache中,如果沒做,即使庫文件明明就在/usr/lib下的,也是不會被使用的,結果編譯過程中抱錯,缺少xxx庫,去查看發現明明就在那放着,搞的想大罵computer蠢豬一個。

 在程序連接時,對於庫文件(靜態庫和共享庫)的搜索路徑,除了上面的設置方式之外,還可以通過 -L 參數顯式指定。因為用 -L 設置的路徑將被優先搜索,所以在連接的時候通常都會以這種方式直接指定要連接的庫的路徑。 

這種設置方式需要 root 權限,以改變 /etc/ld.so.conf 文件並執行 /sbin/ldconfig 命令。而且,當系統重新啟動后,所有的基於 GTK2 的程序在運行時都將使用新安裝的 GTK+ 庫。不幸的是,由於 GTK+ 版本的改變,這有時會給應用程序帶來兼容性的問題,造成某些程序運行不正常。為了避免出現上面的這些情況,在 GTK+ 及其依賴庫的安裝過程中對於庫的搜索路徑的設置將采用另一種方式進行。這種設置方式不需要 root 權限,設置也簡單。

(2). 在環境變量 LD_LIBRARY_PATH 中指明庫的搜索路徑。

 

設置方式:

1
export  LD_LIBRARY_PATH= /opt/gtk/lib :$LD_LIBRARY_PATH

可以用下面的命令查看 LD_LIBRAY_PATH 的設置內容:

1
echo  $LD_LIBRARY_PATH

至此,庫的兩種設置就完成了。

 

查看程序使用的動態庫

ldd  <可執行程序>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM