最近有幸閱讀了《高級C/C++編譯技術》深受啓發,該書深刻淺出地講解了構建過程(編譯、連接)中的各類細節,從多個角度展現了程序與庫文件或代碼的集成方法,提出了面向代碼複用和系統集成的軟件架構設計方法,以及系統開發過程當中疑難問題的解決方案。
如下將回頭記錄下其中的關鍵要點,以便後面查閱。
並非全部代碼改動都會對模塊的功能產生影響,有些改動只是對原有代碼進行一些細微的改進或錯誤修正,而其它一些改動則會修改原有的功能實現,在複雜的版本控制策略中,根據代碼改動的重要性來肯定主次版本號變動,實現向後兼容性。mysql
通常來講,若是動態庫的代碼變動對已有功能進行了修改,那麼就須要增改主版本號sql
(1)對已提供的功能進行修改:刪除某個以前已經支持的功能特性,對原有功能進行完全的修改等緩存
(2)ABI變動致使沒法連接動態庫:刪除功能與整個接口,修改對外提供的函數符號或者修改類的數據結構等數據結構
(3)完全從新設計整個程序或修改程序娥依賴項架構
若是在動態庫的代碼修改過程當中,沒有引入新功能也沒有修改原有的邏輯,那麼一般會增改次版本號,若代碼修改後之修改了次版本號,客戶二進制程序則不須要再從新編譯和連接,在運行過程當中功能也徹底相同,新增的功能一般不會影響到原有的功能,而是在原有的基礎上進行改進函數
ABI接口的變動也屬於次版本號修改的範疇,在這種狀況下一般是在原有的基礎上增添了新的函數、常量、結構和類spa
主要的代碼變動都在內部,不修改ABI接口和原有功能,這時一般會增改修訂版本號操作系統
軟連接是文件系統的中一種元素,存儲了包含另外一個文件路徑的字符串,實際上,咱們能夠說軟鏈接是指向一個已存在的文件,在大多數狀況下,操做系統會將軟連接看成其指向的文件進行處理.net
當提供了新版本的動態庫時,只需將新版本的動態庫文件複製到以前版本的目錄下,而後將軟連接指向修改到新版本的文件便可命令行
$ ln - -f <new version of dynamic library file> <existing soname>
(1)不須要從新構建客戶二進制程序
(2)不須要刪除或覆蓋當前版本的動態庫文件,新舊文件能夠同時存放在相同目錄下
(3)能夠簡單優雅的實現實時配置客戶二進制程序使用更新版本的動態庫
(4)若是升級新版本動態庫後出現問題,能夠優雅地將客戶二進制程序使用的動態庫恢復到老版本
建立:$ ln -s <file path> <softlink path>
重定向並指向其它文件
$ ln -s -f <another file> <existing softlink>
刪除軟鏈接
$ rm -rf <sofylink path>
理論上小版本的增改不該產生任何大的問題,但若是是大版本號的增改,那麼極有可能會產生問題,soname能夠幫助咱們實現相似版本保護機制的功能
(1)經過在構建客戶二進制程序過程當中使用動態庫標示,就能夠限制使用特定主版本號的動態庫,裝載器的設計很是智能,它可以識別出soname規定的能夠升級和不能夠升級的主版本號
(2) soname可以忽略次版本號和修訂版本號的細節,這樣就能夠在不考慮小版本修改的狀況下直接升級了
$ gcc -shared <list of linker inputs> -Wl,-soname,<soname> -o <library filename>
連接器會指定的soname串嵌入二進制文件的DT_SONAME字段中
$ gcc -fPIC -c main.c -o main.o $ gcc -shared main.o -Wl,-soname libtest.so.1 -o libtest.so.1.0.0
readelf -d listtest.so.1.0.0
$ ln -s libtest.so.1 libtest.so $ gcc -fPIC -c main.c -o main.o $ gcc -shared -L./ -ltest main.o out
當客戶二進制文件連接動態庫時,連接器首先獲取動態庫的soname信息,而後將其寫入客戶二進制文件的DT_NEEDED字段
經過這種方法,soname中的版本控制信息會同時存在於動態庫和可執行二進制文件中,娥全部相關組件均可以使用同一版本控制規則(連接器、動態庫文件、客戶二進制文件和裝載器)
不一樣於庫的文件名,任何人均可以簡單地對其進行修改,而修改soname的值就不那麼簡單了,這是由於咱們不只須要對二進制文件進行修改,還有對全部相關的ELF格式文件中存儲的信息進行修改
ldconfig -n <文件路徑>能夠顯示全部依賴的動態庫文件(文件名徹底按照庫文件命名規則顯示),解析每一個動態庫文件的soname信息,併爲每一個解析的soname建立相應的軟連接
ldconfig是一個動態連接庫管理命令,其目的爲了讓動態連接庫爲系統所共享。
默認搜尋/lilb和/usr/lib,以及配置文件/etc/ld.so.conf內所列的目錄下的庫文件。
搜索出可共享的動態連接庫,庫文件的格式爲:lib***.so.**,進而建立出動態裝入程序(ld.so)所需的鏈接和緩存文件。
緩存文件默認爲/etc/ld.so.cache,該文件保存已排好序的動態連接庫名字列表。
ldconfig一般在系統啓動時運行,而當用戶安裝了一個新的動態連接庫時,就須要手工運行這個命令。
一、 -v或--verbose:用此選項時,ldconfig將顯示正在掃描的目錄及搜索到的動態連接庫,還有它所建立的鏈接的名字.
二、-n :用此選項時,ldconfig僅掃描命令行指定的目錄,不掃描默認目錄(/lib,/usr/lib),也不掃描配置文件/etc/ld.so.conf所列的目錄.
三、-N :此選項指示ldconfig不重建緩存文件(/etc/ld.so.cache).若未用-X選項,ldconfig照常更新文件的鏈接.
四、-X : 此選項指示ldconfig不更新文件的鏈接.若未用-N選項,則緩存文件正常更新.
五、-f CONF : 此選項指定動態連接庫的配置文件爲CONF,系統默認爲/etc/ld.so.conf.
六、-C CACHE :此選項指定生成的緩存文件爲CACHE,系統默認的是/etc/ld.so.cache,此文件存放已排好序的可共享的動態連接庫的列表.
七、-r ROOT :此選項改變應用程序的根目錄爲ROOT(是調用chroot函數實現的).選擇此項時,系統默認的配置文件/etc/ld.so.conf,實際對應的爲ROOT/etc/ld.so.conf.如用-r/usr/zzz時,打開配置文件/etc/ld.so.conf時,實際打開的是/usr/zzz/etc/ld.so.conf文件.用此選項,能夠大大增長動態連接庫管理的靈活性.
八、-l :一般狀況下,ldconfig搜索動態連接庫時將自動創建動態連接庫的鏈接.選擇此項時,將進入專家模式,須要手工設置鏈接.通常用戶不用此項.
九、-p或--print-cache :此選項指示ldconfig打印出當前緩存文件所保存的全部共享庫的名字.
十、-c FORMAT 或--format=FORMAT :此選項用於指定緩存文件所使用的格式,共有三種:ld(老格式),new(新格式)和compat(兼容格式,此爲默認格式).
十一、-V : 此選項打印出ldconfig的版本信息,然後退出.
十二、- 或 --help 或--usage : 這三個選項做用相同,都是讓ldconfig打印出其幫助信息,然後退出.、
一、往/lib和/usr/lib裏面加東西,是不用修改/etc/ld.so.conf文件的,可是添加完後須要調用下ldconfig,否則添加的library會找不到。
二、若是添加的library不在/lib和/usr/lib裏面的話,就必定要修改/etc/ld.so.conf文件,往該文件追加library所在的路徑,而後也須要從新調用下ldconfig命令。好比在安裝MySQL的時候,其庫文件/usr/local/mysql/lib,就須要追加到/etc/ld.so.conf文件中。命令以下:
# echo "/usr/local/mysql/lib" >> /etc/ld.so.conf
# ldconfig -v | grep mysql
三、若是添加的library不在/lib或/usr/lib下,可是卻沒有權限操做寫/etc/ld.so.conf文件的話,這時就須要往export裏寫一個全局變量LD_LIBRARY_PATH,就能夠了。