1. 程式人生 > 其它 >Linux動態連結庫.so檔案的命名

Linux動態連結庫.so檔案的命名

我們在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,這個檔案是含有可執行的二進位制程式碼的。

  1. 每個動態庫都有一個以"lib"為字首且以".so.x"為結尾的被稱為 soname

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

ldd

  ldd不是一個可執行程式,而只是一個shell指令碼 ldd能夠顯示可執行模組的dependency(所屬)(所屬),其原理是通過設定一系列的環境變數,如下:LD_TRACE_LOADED_OBJECTS、LD_WARN、LD_BIND_NOW、LD_LIBRARY_VERSION、LD_VERBOSE等。當LD_TRACE_LOADED_OBJECTS環境變數不為空時,任何可執行程式在執行時,它都會只顯示模組的dependency(所屬),而程式並不真正執行。要不你可以在shell終端測試一下,如下: export LD_TRACE_LOADED_OBJECTS=1 再執行任何的程式,如ls等,看看程式的執行結果。

  ldd顯示可執行模組的dependency(所屬)的工作原理,其實質是通過ld-linux.so(elf動態庫的裝載器)來實現的。我們知道,ld-linux.so模組會先於executable模組程式工作,並獲得控制權,因此當上述的那些環境變數被設定時,ld-linux.so選擇了顯示可執行模組的dependency(所屬)。 實際上可以直接執行ld-linux.so模組,如:/lib/ld-linux.so.2 --list program(這相當於ldd program)