Linux中的兩種共享代碼方式靜態(tài)庫和動(dòng)態(tài)庫
1.共享代碼
隨著軟件開發(fā)的發(fā)展,人們發(fā)現(xiàn)很多應(yīng)用的代碼是相同的,也就是說這些代碼可以被共享,因此,人們提出了靜態(tài)庫和動(dòng)態(tài)庫兩種方案來解決代碼共享的問題。
2.靜態(tài)庫
靜態(tài)庫,顧名思義,它是靜態(tài)的,也就是說它不會被動(dòng)態(tài)編譯,它只會靜態(tài)編譯,節(jié)省了編譯時(shí)間,提高了編譯速度。同一份靜態(tài)庫,可以被多個(gè)程序進(jìn)行編譯,也就實(shí)現(xiàn)了代碼的復(fù)用共享。
3.動(dòng)態(tài)庫
動(dòng)態(tài)庫,就是程序應(yīng)用啟動(dòng)的時(shí)候,動(dòng)態(tài)加載的,因?yàn)樗话闶窃谙到y(tǒng)運(yùn)行的時(shí)候就已經(jīng)運(yùn)行的動(dòng)態(tài)庫,因此其它應(yīng)用可以直接使用它,并且同一個(gè)動(dòng)態(tài)庫可以被多個(gè)應(yīng)用共享使用,在系統(tǒng)中對于一個(gè)動(dòng)態(tài)庫只會存在一份,這大大節(jié)省了內(nèi)存空間,大大提升了系統(tǒng)的性能。
在linux系統(tǒng)中,動(dòng)態(tài)庫一般以.so形式命名,表示share object。
很多時(shí)候,你很難知道一個(gè)應(yīng)用需要哪些動(dòng)態(tài)庫,不過我們有個(gè)工具ldd可以幫助你查看一個(gè)應(yīng)用需要哪些動(dòng)態(tài)庫。
如果一些動(dòng)態(tài)庫沒有找到的話,程序就無法正常運(yùn)行,這也是你會看到很多程序啟動(dòng)的時(shí)候提示缺少xx.so的原因。
如果你的程序需要xx.so動(dòng)態(tài)庫,而系統(tǒng)路徑中沒有它的話,你可以通過LD_LIBRARY_PATH 將你需要的動(dòng)態(tài)庫添加到系統(tǒng)路徑中。
查看一個(gè)文件使用了什么連接器可以使用file命令,一般程序都會使用/lib64/ld-linux-x86-64.so.2這個(gè)文件,而這個(gè)文件其實(shí)會指向一個(gè)ld-2.xx.so文件。
4.動(dòng)態(tài)加載器ld.so
在linux系統(tǒng)中,動(dòng)態(tài)庫都是通過ld.so來進(jìn)行管理的,它首先會根據(jù)應(yīng)用的編譯信息查找相對或者絕對路徑來查找動(dòng)態(tài)庫,然后就會通過環(huán)境變量LD_LIBRARY_PATH來查找動(dòng)態(tài)庫,最后它會根據(jù)/etc/ld.so.cache緩存來查找動(dòng)態(tài)庫。
因此,當(dāng)我們像系統(tǒng)中添加一個(gè)動(dòng)態(tài)庫的時(shí)候我們有兩種方式,一種是直接放入到/usr/lib64文件夾里面,不過這需要你有root權(quán)限,第二種就是通過LD_LIBRARY_PATH配置我們的動(dòng)態(tài)庫路徑。
5.程序引入動(dòng)態(tài)庫
在程序編譯的時(shí)候,我們可以通過指定編譯參數(shù)來引入動(dòng)態(tài)庫。
例如,當(dāng)我們使用gcc來進(jìn)行編譯的時(shí)候,我們可以通過-l來表示鏈接庫名稱,通過-Ldir來指定動(dòng)態(tài)庫路徑。 當(dāng)我們使用g++來進(jìn)行編譯的時(shí)候,-L可以用來指定動(dòng)態(tài)庫的路徑,進(jìn)行程序動(dòng)態(tài)庫的鏈接。
6.總結(jié)
人們?yōu)榱藴p少冗余代碼,提出了共享庫的概念,在鏈接的時(shí)候和程序一同打包成一個(gè)可執(zhí)行文件的這個(gè)庫就是靜態(tài)庫,反之,在鏈接的時(shí)候不將動(dòng)態(tài)庫打包進(jìn)可執(zhí)行文件,只是標(biāo)記運(yùn)行需要此共享庫,這就是動(dòng)態(tài)庫。
靜態(tài)庫是同程序一同打包的,因此它不需要環(huán)境的依賴,而動(dòng)態(tài)庫是程序執(zhí)行時(shí)候需要引用的,因此它對環(huán)境有依賴,這也是為什么很多依賴動(dòng)態(tài)庫的文件執(zhí)行的時(shí)候報(bào)錯(cuò)缺少動(dòng)態(tài)庫的原因,那是操作系統(tǒng)缺少對應(yīng)的動(dòng)態(tài)庫導(dǎo)致的。
靜態(tài)庫增大了程序的體積,同時(shí)多個(gè)程序?qū)ο嗤o態(tài)庫的鏈接也占用了大量的內(nèi)存,因此,才有了動(dòng)態(tài)庫的出現(xiàn),可以說兩者都是為了解決代碼共享復(fù)用的問題,而且兩者是相輔相成的關(guān)系。