溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

unix平臺動態(tài)連接庫的管理是什么

發(fā)布時間:2021-11-09 09:44:35 來源:億速云 閱讀:127 作者:柒染 欄目:建站服務器

這篇文章給大家介紹unix平臺動態(tài)連接庫的管理是什么,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

    世界上唯一不變的是變化,對于動態(tài)連接庫更是如此。動態(tài)庫天生為方便程序的更新而設計,只需要替代庫文件,無需重新編譯主程序,即可運行更新后的版本。另外,動態(tài)庫是多應用共享的,多個程序使用同一個庫,那么庫只會加載一份。
    但是,現(xiàn)實往往不這么簡單。既然動態(tài)庫有新版本,那就會有與舊版本兼容或者不兼容的情況出現(xiàn)。當系統(tǒng)里存在多個使用此動態(tài)庫的應用程序時,如果是兼容舊版本的更新還好,如果是不兼容,那么使用舊版本的應用程序就會受影響不能正常運行。特別的,當動態(tài)庫集中放在系統(tǒng)指定的庫目錄下時(windows的system32),版本的沖突就形成了著名的“windows dll hell”。

    為了解決這個問題,很多UNIX系統(tǒng)使用了ELF格式的DT_SONAME字段來應對。例如,linux的ld命令中,就有這么一個選項。
       -h name
       -soname=name
           When creating an ELF shared object, set the internal DT_SONAME
           field to the specified name.  When an executable is linked with a
           shared object which has a DT_SONAME field, then when the executable
           is run the dynamic linker will attempt to load the shared object
           specified by the DT_SONAME field rather than the using the file
           name given to the linker.
    表示使用-h或者-soname選項,可以在動態(tài)庫里指定DT_SONAME字段,保存運行時查找的動態(tài)庫名字,使得編譯時和運行時動態(tài)庫名可以不同。例如,編譯libwel.so時使用-soname=libwel.so.1,那么編譯可執(zhí)行程序時-lwel,連接libwel.so,會記錄運行時在搜索路徑查找libwel.so.1加載。

    ELF是一種應用非常廣泛的二進制目標格式,與之類似的,UNIX的二進制目標還有a.out格式(SCO UNIX),XCOFF格式(AIX)。這兩種格式就無法支持soname了。

    那么,如何使多個版本的動態(tài)連接庫同時支持呢,總結(jié)一下使用這種命名方式既可以新舊不兼容版本共存,又可以兼容版本正常升級。動態(tài)庫命名為libxxx.so.n.m,soname名為libxxx.so.n,建立軟連接libxxx.so指向最新的n版本libxxx.so.n供編譯可執(zhí)行程序使用,建立軟連接libxxx.so.n指向版本n最新的m版本。這樣,n的變化表示不兼容舊版本的改動,相同n下m的變化表示兼容n版本的改動。
    還是以libwel.so舉例。1.0版本的wel.c提供的函數(shù)void welcome(void) { printf("aaa\n"); },編譯成庫libwel.so.1.0,soname為libwel.so.1。建立軟連接libwel.so.1,libwel.so。使用1.0庫的主程序main1.c調(diào)用welcome(),編譯成main1程序。1.1版本的wel.c改成void welcome(void) { printf("bbb\n"); },動態(tài)庫只修改內(nèi)部實現(xiàn),對外接口兼容1.0版本,編譯成庫libwel.so.1.1。此時更新軟連接libwel.so.1為libwel.so.1.1,主程序main1無需變動,即可輸出更新后的bbb。2.0版本的wel.c改變了對外接口,提供的函數(shù)void welcome(char *p) { printf("%s\n",p); }。編譯成庫libwel.so.2.0,soname為libwel.so.2。建立軟連接libwel.so.2,libwel.so。使用2.0庫的主程序main2.c應以一個參數(shù)調(diào)用welcome("test")。main1和main2主程序互不兼容,必須分別調(diào)用版本1和版本2的庫。此時,庫目錄下存在libwel.so.1指向1.1版本,libwel.so.2指向2.0版本,main1會連接1.1版本運行,main2會連接2.0版本運行。由此可見,小版本升級時應用程序自動使用最新版本,大版本升級時,使用舊版本的“過時”應用程序不受影響,從而避免了動態(tài)庫版本的混亂。

    同樣,以link方式為例,給出各UNIX平臺加設soname的動態(tài)庫編譯方法。(AIX不支持)

 linux:
  編譯libwel.so:
   gcc -fPIC -shared -Wl,-soname,libwel.so.1 -o libwel.so.1.0 wel.c -lc
   ln -sf libwel.so.1.0 libwel.so.1
   ln -sf libwel.so.1 libwel.so
    -Wl,-soname,libwel.so.1 指定libwel.so.1.0的實際soname為libwel.so.1

 sco unix open server:
  編譯libwel.so:
   cc -K pic -G -h libwel.so.1 -o libwel.so.1.0 wel.c -lc
   ln -sf libwel.so.1.0 libwel.so.1
   ln -sf libwel.so.1 libwel.so
    -h libwel.so.1 指定libwel.so.1.0的實際soname為libwel.so.1

 HP UX:
  編譯libwel.so:
   cc +z -c wel.c
   ld -b -o libwel.sl.1.0 wel.o +h libwel.sl.1 -lc
   ln -sf libwel.sl.1.0 libwel.sl.1
   ln -sf libwel.sl.1 libwel.sl
    +h libwel.sl.1 指定libwel.sl.1.0的實際soname為libwel.sl.1

 SUN OS:
  編譯libwel.so:
   cc -G -h libwel.so.1 -o libwel.so.1.0 wel.c -lc
   ln -sf libwel.so.1.0 libwel.so.1
   ln -sf libwel.so.1 libwel.so
    -h libwel.so.1 指定libwel.so.1.0的實際soname為libwel.so.1

關于unix平臺動態(tài)連接庫的管理是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI