6、linux共享庫的組織

weixin_34321977發表於2017-03-13
共享庫版本

  • 1、相容性,為了使共享庫能夠有更好的二進位制相容性,最好做到不要使用c++做介面,如果一定要使用需注意(1)不在介面類中使用虛擬函式;(2)不改變類中任何成員變數的位置和型別
  • 2、共享庫版本命名
libname.so.x.y.z
x主版本號,x不同共享庫不相容
y次版本號,表示增量升級,新增新介面
z釋出版本號,修改錯誤和效能方面的問題
  • 3、SO-NAME,表示一個庫的介面,體現一個程式依賴的共享庫所需要的最少資訊
libname.so.x
linux中通常是以so-name作為連結,指向一個實際的最新的動態庫,每次按照新共享庫後需執行ldconfig將軟連結指向最新的共享庫
libname.so.x->libname.so.x.y.z

由於歷史原因c語言庫和動態連結器的so-name如下

ld-linux.so->ld-2.6.1.so
libc.so.6->libc-2.6.1.so
符號版本

之所以提出符號版本的概念是因為次版本交會問題,使用SO-NAME在程式執行時只判斷了主版本,但是主版本號相同的共享庫也存在的一定的介面數量的差別,這將導致依賴於SO-NAME並不能保證程式可以正常執行(這個也就是次版本交會問題)。
符號版本的基本思路是讓共享庫的每一個匯入匯出符號都有一個相關聯的版本號,做法上類似名稱修飾的方式。

共享庫的系統路徑

目前大多數linux系統都支援一個叫做FHS(file hierarchy standard)的標準,規定系統中系統檔案應該如何放置,各個目錄的結構、組織和作用
FHS中規定了三個共享庫的放置目錄

  • 1、/lib存放系統最關鍵和基礎的共享庫,主要是/bin、/sbin和系統啟動需要使用到的共享庫
  • 2、/usr/lib主要存放非系統執行時所需要的關鍵性共享庫,包括一些開發庫等
  • 3、/usr/local/lib主要存放第三方應用程式的庫
共享庫的查詢過程

動態連結模組所依賴的模組路徑儲存在.dynamic由DT_NEED型別項表示,通常存放的共享庫的相對路徑,連結在連結時就需要查詢到共享庫的實際位置,查詢順序如下

  • 0、LD_LIBRARY_PATH變數所指示的路徑下查詢,這個變數可以臨時修改某個程式的共享庫查詢路徑,指定了該變數連結器在查詢共享庫時會優先查詢該變數所指示的路徑
  • 1、查詢/etc/ld.so.cache,由ldconfig建立更新
  • 2、查詢/lib和/usr/lib目錄
與連結相關的環境變數

  • 1、LD_LIBRARY_PATH
    這個變數可以臨時修改某個程式的共享庫查詢路徑,指定了該變數連結器在查詢共享庫時會優先查詢該變數所指示的路徑
  • 2、LD_PRLOAD
    這個變數可以在程式裝載其他共享庫時,指定預先裝載一些共享庫,優先於LD_LIBRARY_PATH,且無論程式是否依賴該共享庫,均會被載入。(由於該機制的存在,同時還有載入時的全域性符號介入機制,導致可以利用該變數對標準庫或者其他庫中的符號進行替換)
  • 3、LD_DEBUG
    這個變數可以開啟動態連結的除錯功能,檢視到連結的過程中的各種詳細資訊,如共享庫的載入、符號的解析、路徑查詢等過程
共享庫的建立安裝

1、建立

gcc -shared -fPIC -Wl,-soname,my_soname -o libname source_file
-shared 表示生成共享庫
-fPIC表示使用地址無關程式碼技術
-Wl表示把後面的引數傳遞給連結器,例如-soname表示指定共享庫的SO-NAME

2、安裝
複製到/lib或者/usr/lib或者/usr/local/lib目錄下,然後執行ldconfig
3、共享庫指令碼
前面提到共享庫通常是elf的dso檔案,但共享庫也可以是一個符合一定格式的指令碼,通過這種指令碼可以把結構現有的共享庫通過一定的方式組合起來,從使用者的角度就是一個新的共享庫,格式如下

GROUP( /lib/libc.so.6 /lib/libm.so.2)

end~

相關文章