撰/ahliu
前言
動態連結程式庫(Shared library)是在程式開始執行時才載入的,其優點在於(1)減少執行檔的大小,(2)更新程式庫而無需重新編譯其他程式,以及(3)甚至可在程式執行時更改程式庫。
在使用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 library檔案架構
一
般我們都會將程式庫放在/usr/lib中,但通常我會都會依照GNU Directory Variables
Standard及FHS(Filesystem Hierarchy
Standard)來決定程式庫的擺放位置,若根據GNU的標準所說,所有發佈式(非原本系統及系統服務額外所需的)的程式庫都應放在
/usr/local/lib,系統管理員亦需加入/usr/local/lib為程式庫連結目錄,只有與系統有關的程式庫才會被放進/usr/lib;
而根據FHS的標準而言,非系統服務用的程式庫也可放在/usr/lib之下的目錄裡。請留意GNU的標準與FHS並沒有衝突,因為GNU的標準是以程式
庫開發者的角度來想,即是你需要一個外來的程式庫來發展你的程式時,你會把它放在/usr/local/lib;而FHS則是以使用者的角度來想,當你安
裝一軟件時所需要的額外程式庫,則你多數會把它放在/usr/lib。
在
安裝程式庫時,你需把以real
name命名的程式庫放在適當的目錄(/usr/lib或/usr/local/lib或其他,以後例子均使用/usr/lib),然後建立兩條分別以
soname及linker name命名的symbolic link指向real
name程式庫檔案,當然你也可以用ldconfig來協助你建立symbolic及cache,但ldconfig並不會為你建立以linker
name命名的symbolic link, 而且自行建立看起來更快捷及可靠(不知大家會否同意)。
建立Shared library(使用gcc)
首
先要以-fPIC選項建立一object file,PIC(position-independent code),是shared
library必需使用的選項,這令shared library擁有自己的動態記憶體區塊(i.e. 它使用全域記憶體偏移量表(global
offset table,GOT),不受主程式的記憶體限制):
gcc -fPIC -c -Wall test.c
這指令會產生test.o,然後再需要以「-W1,-soname」連結選項將目的檔編譯成「.so」:
gcc -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.0.1 test.o -lc
整個編譯程序就是這樣了,libtest.so.1.0.1就是以real name命名的程式庫檔,你需要把它放到/usr/lib,然後建立soname及linker name的symbol link。
使用Shared library
使用的方法十分簡單,每次編譯時都加上「-ltest」(或其他「-lxxxx」)即可,例如:
gcc main.c -ltest -o main
就能使用剛才所製作的libtest.so.1.0.1。
相關連結:
- FHS參考文件