国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Linux > 正文

再探Linux動態(tài)鏈接 -- 關(guān)于動態(tài)庫的基礎(chǔ)知識

2024-06-28 13:26:24
字體:
供稿:網(wǎng)友
再探linux動態(tài)鏈接 -- 關(guān)于動態(tài)庫的基礎(chǔ)知識

在近一段時間里,由于多次參與相關(guān)專業(yè)軟件Linux運行環(huán)境建設(shè),深感有必要將這些知識理一理,供往后參考。

編譯時和運行時

縱觀程序編譯整個過程,細(xì)分可分為編譯(Compiling,指的是語言到平臺相關(guān)目標(biāo)文件這一層次)和鏈接(Linking,指目標(biāo)文件到最終形成可執(zhí)行文件這一層次),這個總的過程可稱為編譯時;就動態(tài)鏈接而言,還存在一個運行時,即程序在被操作系統(tǒng)加載的過程中,系統(tǒng)將該程序需要的動態(tài)庫加載至內(nèi)存到程序開始運行的這一段過程。明確這兩個過程在一般linux開發(fā)中的地位,以及了解每個“時”所遇要的文件、所運行的工具對理解linux動態(tài)鏈接很重要。

Linux共享庫命名規(guī)范

回顧linux對動態(tài)庫的命名規(guī)則,在一般情況下,均命名為libname.so.x.y.z。各版本號意義與兼容性標(biāo)準(zhǔn)如下表所示,這些也是程序員進行庫程序設(shè)計是應(yīng)該盡量遵守的設(shè)計規(guī)范。

版本號

意義

x

主版本號,表示重大升級,不同主版本的庫之間是不兼容的

y

次版本號,表示增量升級,高次版本向后兼容低次版本號的庫

z

發(fā)布版本號,表示一些錯誤修正,性能改進,不同發(fā)布版本號之間完全兼容

這樣的設(shè)計很容易帶來一個問題,即動態(tài)庫如何進行有效地升級,而不要求依賴它的應(yīng)用程序重新編譯?比如demo.out依賴libsmath.so.1.0.0(該名稱在編譯已指定,儲存在ELF文件的DT_NEEDED段中),現(xiàn)對該庫升級至1.1.0,但demo.out程序已經(jīng)無法使用新版本的庫。為解決這樣的問題,Linux引入一種新的機制SO-NANE.

SO-NAME版本控制

由上可知,共享庫的主版本和次版本決定該共享庫的接口,則對于依賴某庫的應(yīng)用程序,最小限度上只需記錄該庫的主版本號,具體的版本即次版本和發(fā)布版本,可以交給動態(tài)鏈接器(一般為ld-linux.so)來選擇,這樣便可以在一定程度上解決上述的問題。

具體設(shè)計實現(xiàn)方面,對于libname.so.x.y.z,省略其y和z,只記錄成libname.so.x即為該共享庫的SO-NAME,在需要該庫的應(yīng)用程序的DT_NEEDED段中記錄這個SO-NAME,同時在動態(tài)鏈接器的庫搜索目錄添加這個庫的軟鏈接,指定為libname.so.x(可通過設(shè)置/etc/ld.so.conf或設(shè)置環(huán)境變量LD_LIBRARY_PATH)。這樣對于libname.so.x.y.z的次版本和發(fā)布版本的升級,只需更新該軟鏈接就行,應(yīng)用程序無須重新編譯。

同時,SO-NAME也會被記錄在該動態(tài)庫內(nèi),供ldconfig工具自動更新軟鏈接所用,這也就是每次安裝新軟件包后一般會運行該工具的原因。

以上這些均是對于運行時而言的,在編譯時同樣需要一些該庫的信息,指定所需要的庫,即gcc的-lname選項。該選項主要是傳遞給鏈接器(ld,而非運行時所用的ld-linux.so),鏈接器會在庫搜索目錄(可通過設(shè)置-rpath參數(shù)或LIBRARY_PATH環(huán)境變量)搜索libname.so文件,所以為了能使用該庫進行開發(fā),需要在以上目錄設(shè)定指向libname.so.x或libname.so.x.y.z的軟鏈接,名稱為libname.so.這項工作一般需手動完成。

示例

(下述例子中,smath.h、libsmath.so為編譯時需要文件;libsmath.so.1、libsmath.so.1.0.0為運行時所需文件)

假設(shè)需要自定義編寫一套數(shù)學(xué)庫,其中有Add和Sub等函數(shù)

1 //smath.h2 3 int Add(int,int);4 5 int Sub(int,int);
 1 //smath.c 2  3 int Add(int a,int b) 4  5 { 6  7     return a+b; 8  9 }10 11 int Sub(int a,int b)12 13 {14 15     return a-b;16 17 }

①編譯

按照gcc操作手冊

執(zhí)行

gcc -shared -fPIC -Wl, -soname,libsmath.so.1 -o libmath.so.1.0.0 smath.c

(若不指定-soname,則該庫沒有SO-NAME,DT_NEEDED中記錄為空)

②安裝

復(fù)制頭文件

cp smath.h ~/include

安裝至自定義目錄(非/lib、/usr/lib等),假設(shè)安裝至~/lib下

cp libsmath.so.1.0.0 ~/libcd ~/libln -s libsmath.so.1.0.0 libsmath.so.1ln -s libsmath.so.1 libsmath.so

③使用

保證smath.h 、libsmath.so在相關(guān)搜索目錄下(編譯鏈接用)

export C_INCLUDE_PATH=$HOME/includeexport LIBRARY_PATH=$HOME/include

(也可設(shè)置gcc相關(guān)參數(shù)設(shè)置)

則現(xiàn)在可使用gcc編譯如下代碼

main.c#include <stdio.h>#include <smath.h>int main(){    int a=3,b=5;    PRintf(“%d + %d = %d/n”,a,b,Add(a,b));    return 0;}

編譯

gcc -omain.out -lsmath main.c 

④運行

保證libsmath.so.1在相關(guān)搜索目錄下(運行鏈接用)

export LD_LIBRARY_PATH=$HOME/lib

(也可設(shè)置/etc/ld.so.conf目錄)

即可運行

參考

《程序員的自我修養(yǎng)——鏈接、裝載與庫》 第8章

Working with libraries and the linker -- http://bottomupcs.sourceforge.net/csbu/x4012.htm


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 凉山| 浮梁县| 昔阳县| 德清县| 平邑县| 蓬溪县| 富顺县| 平昌县| 长乐市| 绥芬河市| 都兰县| 砚山县| 宜阳县| 赞皇县| 宜丰县| 斗六市| 即墨市| 汕头市| 吴江市| 保靖县| 远安县| 丹江口市| 安乡县| 岑溪市| 四会市| 麻城市| 黄浦区| 曲松县| 上蔡县| 鄂托克旗| 澜沧| 定远县| 读书| 静宁县| 海阳市| 宜宾市| 玉林市| 宿州市| 伊宁市| 吉木乃县| 哈巴河县|