資源描述:
《linux下gcc生成與使用靜態(tài)庫與動(dòng)態(tài)庫詳解》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫。
1、Linux下Gcc生成和使用靜態(tài)庫和動(dòng)態(tài)庫詳解一、基本概念1.1什么是庫在windows平臺和linux平臺下都大量存在著庫。本質(zhì)上來說庫是一種可執(zhí)行代碼的二進(jìn)制形式,可以被操作系統(tǒng)載入內(nèi)存執(zhí)行。由于windows和linux的平臺不同(主要是編譯器、匯編器和連接器的不同),因此二者庫的二進(jìn)制是不兼容的。本文僅限于介紹linux下的庫。??1.2庫的種類linux下的庫有兩種:靜態(tài)庫和共享庫(動(dòng)態(tài)庫)。二者的不同點(diǎn)在于代碼被載入的時(shí)刻不同。靜態(tài)庫的代碼在編譯過程中已經(jīng)被載入可執(zhí)行程序,因此體積較大。共享庫的代碼是在可執(zhí)行程序運(yùn)行時(shí)才
2、載入內(nèi)存的,在編譯過程中僅簡單的引用,因此代碼體積較小。??1.3庫存在的意義庫是別人寫好的現(xiàn)有的,成熟的,可以復(fù)用的代碼,你可以使用但要記得遵守許可協(xié)議?,F(xiàn)實(shí)中每個(gè)程序都要依賴很多基礎(chǔ)的底層庫,不可能每個(gè)人的代碼都從零開始,因此庫的存在意義非同尋常。共享庫的好處是,不同的應(yīng)用程序如果調(diào)用相同的庫,那么在內(nèi)存里只需要有一份該共享庫的實(shí)例。??1.4庫文件是如何產(chǎn)生的在linux下靜態(tài)庫的后綴是.a,它的產(chǎn)生分兩步Step1.由源文件編譯生成一堆.o,每個(gè).o里都包含這個(gè)編譯單元的符號表Step2.ar命令將很多.o轉(zhuǎn)換成.a,成為靜
3、態(tài)庫動(dòng)態(tài)庫的后綴是.so,它由gcc加特定參數(shù)編譯產(chǎn)生。具體方法參見后文實(shí)例。?1.5庫文件是如何命名的,有沒有什么規(guī)范在linux下,庫文件一般放在/usr/lib和/lib下,靜態(tài)庫的名字一般為libxxxx.a,其中xxxx是該lib的名稱動(dòng)態(tài)庫的名字一般為libxxxx.so.major.minor,xxxx是該lib的名稱,major是主版本號,?minor是副版本號??1.6如何知道一個(gè)可執(zhí)行程序依賴哪些庫ldd命令可以查看一個(gè)可執(zhí)行程序依賴的共享庫,例如#ldd/bin/lnlibc.so.6=>/lib/libc.s
4、o.6(0×40021000)/lib/ld-linux.so.2=>/lib/ld-linux.so.2(0×40000000)可以看到ln命令依賴于libc庫和ld-linux庫??1.7可執(zhí)行程序在執(zhí)行的時(shí)候如何定位共享庫文件當(dāng)系統(tǒng)加載可執(zhí)行代碼時(shí)候,能夠知道其所依賴的庫的名字,但是還需要知道絕對路徑。此時(shí)就需要系統(tǒng)動(dòng)態(tài)載入器(dynamiclinker/loader)對于elf格式的可執(zhí)行程序,是由ld-linux.so*來完成的,它先后搜索elf文件的?DT_RPATH段—環(huán)境變量LD_LIBRARY_PATH—/etc/
5、ld.so.cache文件列表—/lib/,/usr/lib目錄找到庫文件后將其載入內(nèi)存如:exportLD_LIBRARY_PATH=’pwd’將當(dāng)前文件目錄添加為共享目錄?1.8在新安裝一個(gè)庫之后如何讓系統(tǒng)能夠找到他如果安裝在/lib或者/usr/lib下,那么ld默認(rèn)能夠找到,無需其他操作。如果安裝在其他目錄,需要將其添加到/etc/ld.so.cache文件中,步驟如下1.編輯/etc/ld.so.conf文件,加入庫文件所在目錄的路徑2.運(yùn)行l(wèi)dconfig,該命令會(huì)重建/etc/ld.so.cache文件二、用gcc生成
6、靜態(tài)和動(dòng)態(tài)鏈接庫的示例我們通常把一些公用函數(shù)制作成函數(shù)庫,供其它程序使用。函數(shù)庫分為靜態(tài)庫和動(dòng)態(tài)庫兩種。?靜態(tài)庫在程序編譯時(shí)會(huì)被連接到目標(biāo)代碼中,程序運(yùn)行時(shí)將不再需要該靜態(tài)庫。?動(dòng)態(tài)庫在程序編譯時(shí)并不會(huì)被連接到目標(biāo)代碼中,而是在程序運(yùn)行是才被載入,因此在程序運(yùn)行時(shí)還需要?jiǎng)討B(tài)庫存在。?本文主要通過舉例來說明在Linux中如何創(chuàng)建靜態(tài)庫和動(dòng)態(tài)庫,以及使用它們。?為了便于闡述,我們先做一部分準(zhǔn)備工作。?2.1準(zhǔn)備好測試代碼hello.h、hello.c和main.c;hello.h(見程序1)為該函數(shù)庫的頭文件。?hello.c(見程序2
7、)是函數(shù)庫的源程序,其中包含公用函數(shù)hello,該函數(shù)將在屏幕上輸出"HelloXXX!"。?main.c(見程序3)為測試庫文件的主程序,在主程序中調(diào)用了公用函數(shù)hello。??程序1:hello.h#ifndefHELLO_H?#defineHELLO_H???voidhello(constchar*name);???#endif程序2:hello.c#include?voidhello(constchar*name){??????printf("Hello%s!",name);?}程序3:main.c#i
8、nclude"hello.h"??intmain()??{??????hello("everyone");??????return0;??}2.2問題的提出注意:這個(gè)時(shí)候,我們編譯好的hello.o是無法通過gcc–o?編譯的,這個(gè)道