201005012126Linux動態&靜態函式庫解說

Linux動態&靜態函式庫解說
動態連結程式庫(Shared library)是在程式開始執行時才載入的,其優點在於(1)減少執行檔的大小,(2)更新程式庫而無需重新編譯其他程式,以及(3)甚至可在程式執行時更改程式庫。

每一個shared library都有一個以「lib」開頭的程式庫名稱,然後加上程式庫的名稱,在名稱末端再加上「.so」或「.a」,其中「.so」的函式庫代表這是共享(share)函式庫,而「.a」的函式庫代表這是一個靜態(static)函式庫。在應用程式編譯時,若使用靜態函式庫的話,則函式庫中的元件會連結到我們的執行檔中,此時執行檔的大小會比較大,但好處是當我們在執行程式時,就不需要再函式庫的配合了。
在使用shared library前,你需要知道與shared library有關的名詞:
soname:每一個shared library都有一個以「lib」開頭的程式庫名稱,然後加上程式庫的名稱,在名稱末端再加上「.so」,以及period(i.e.「.」號)與版本號碼。一個全稱程式庫名稱(fully-qualified soname)應該是「libxxxx.so.N」,「xxxx」是程式庫名稱,「N」是版本號碼。
real name: 真正載有已編譯程式碼的檔案名稱,傳統上棋檔名要包含「lib」、程式庫名稱、「.so」、主次版本號碼及發佈版本號碼,例如「libxxxx.so.N1.N2.N3」。 linker name: 編譯器所搜尋的程式庫名稱,傳統上就是real name刪去所有版本號碼後的名稱,例如「libxxxx.so」
建立動態(Shared)函式庫
首先要以-fPIC選項建立一object file,PIC(position-independent code),是shared
library必需使用的選項,這令shared library擁有自己的動態記憶體區塊(i.e. 它使用全域記憶體偏移量表(global offset table,GOT),不受主程式的記憶體限制):
gcc -fPIC -c -Wall initapi.c
gcc -fPIC -c -Wall randapi.c
然後再將目的檔編譯成「.so」:
gcc -shared initapi.o randapi.o –o libmyrand2.so
整個編譯程序就是這樣了。

製作靜態(static)函式庫
步驟一
gcc -c -Wall initapi.c
gcc -c -Wall randapi.c
步驟二
執行ar指令,將目的檔加入靜態函式庫中
ar –cru libmyrand.a initapi.o randapi.o
在執行上述指令後,會將initapi.o及randapi.o加入至libmyrand.a靜態函式庫中。
其中我們在ar指令中加入「-cru」的選項,這是建立或加入目的檔的標準作法,選項c指定要建立靜態函式庫,選項r告知ar取代其中已存在的目的檔,選項u則為一個安全選項,它告知ar欲取代的目的檔必須比已存在的目的檔還新才行。
好用指令
ldd指令可以查看執行檔在執行時所需要的共享函式庫。
用法: ldd 執行檔

補充:
解 決 /usr/bin/ld: cannot find -lxxx 問題
例如:出現   /usr/bin/ld: cannot find -lXtst
代表在/usr/lib的目錄下找不到 libXtst.so 檔,那麼就表示系統沒有安裝libXtst的函式庫。要安裝的話即可用libXtst為關鍵字安裝,通常就可找到libXtst-dev便是。
若出現找不到lib檔,但在其他目錄下明明存在時,例如出現錯誤
error while loading shared libraries: libvlc.so.5: cannot open shared object file: No such file or directory
但用
ianwolf@ubuntu:~/桌面$ whereis libvlc.so.5
libvlc.so: /usr/local/lib/libvlc.so.5 /usr/local/lib/libvlc.so
卻能在其他地方找到
則可用
sudo /sbin/ldconfig
指令來解決

參考資料:http://www.wretch.cc/blog/dakiyo/11478353

回應
關鍵字
    沒有新回應!