from http://blog.csdn.net/autumnqin/article/details/5444168 Library 可分成三種, static ,、 shared 與 dynamically loaded ,。 1. Static libraries Static 鏈接庫用于靜態(tài)鏈接,簡單講是把一堆 object 檔用 ar(archiver) 包裝集合起來,,文件名以 `.a' 結(jié)尾,。優(yōu)點是執(zhí)行效能通常會比后兩者快,而且因為是靜態(tài)鏈接,,所以不易發(fā)生執(zhí)行時找不到 library 或版本錯置而無法執(zhí)行的問題,。缺點則是檔案較大,維護度較低,;例如 library 如果發(fā)現(xiàn) bug 需要更新,,那么就必須重新連結(jié)執(zhí)行檔。 1.1 編譯 編譯方式很簡單,,先例用 `-c' 編出 object 檔,,再用 ar 包起來即可,。 ____ hello.c ____ ____ world.c ____ ____ mylib.h ____ $ gcc -c hello.c world.c /* 編出 hello.o 與 world.o */ 這樣就可以建出一個檔名為 libmylib.a 的檔。輸出的檔名其實沒有硬性規(guī)定,,但如果想要配合 gcc 的 '-l' 參數(shù)來連結(jié),,一定要以 `lib' 開頭,中間是你要的 library 名稱,,然后緊接著 `.a' 結(jié)尾,。 1.2 使用 ____ main.c ____ 使用上就像與一般的 object 檔連結(jié)沒有差別。 $ gcc main.c libmylib.a 也可以配合 gcc 的 `-l' 參數(shù)使用 $ gcc main.c -L. -lmylib `-Ldir' 參數(shù)用來指定要搜尋鏈接庫的目錄,, `.' 表示搜尋現(xiàn)在所在的目錄,。通常默認會搜 /usr/lib 或 /lib 等目錄。 $ ./a.out
Shared library 會在程序執(zhí)行起始時才被自動加載,。因為鏈接庫與執(zhí)行檔是分離的,,所以維護彈性較好。有兩點要注意,, shared library 是在程序起始時就要被加載,,而不是執(zhí)行中用到才加載,而且在連結(jié)階段需要有該鏈接庫才能進行連結(jié),。 首先有一些名詞要弄懂,, soname 、 real name 與 linker name ,。 soname 用來表示是一個特定 library 的名稱,,像是 libmylib.so.1 。前面以 `lib' 開頭,,接著是該 library 的名稱,,然后是 `.so' ,接著 real name 是實際放有 library 程序的文件名,,后面會再加上 minor 版號與 一般來說,版號的改變規(guī)則是 ( 印象中在 APress-Difinitive Guide to GCC 中有提到,,但目前手邊沒這本書 ) ,,最后綴的 release 版號用于程序內(nèi)容的修正,,接口完全沒有改變。中間的 minor 用于有新增加接口,,但相舊接口沒改變,,所以與舊版本兼容。最前面的 version 版號用于原接口有移除或改變,,與舊版不兼容時,。 linker name 是用于連結(jié)時的名稱,是不含版號的 soname ,,如 : libmylib.so ,。 2.1 編譯 $ gcc -c -fPIC hello.c world.c 編譯時要加上 -fPIC 用來產(chǎn)生 position-independent code 。也可以用 -fpic 參數(shù),。 ( 不太清楚差異,,只知道 -fPIC 較通用于不同平臺,但產(chǎn)生的 code 較大,,而且編譯速度較慢 ) ,。 $ gcc -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0.0 / -shared 表示要編譯成 shared library 若不指定 soname 的話,,在編譯結(jié)連后的執(zhí)行檔會以連時的 library 檔名為 soname ,并載入他,。否則是載入 soname 指定的 library 檔案,。 可以利用 objdump 來看 library 的 soname 。 $ objdump -p libmylib.so | grep SONAME 若不指名 -soname 參數(shù)的話,,則 library 不會有這個字段數(shù)據(jù),。 在編譯后再用 ln 來建立 soname 與 linker name 兩個檔案。
與使用 static library 同,。 $ gcc main.c libmylib.so 以上直接指定與 libmylib.so 連結(jié),。 或用 $ gcc main.c -L. -lmylib linker 會搜尋 libmylib.so 來進行連結(jié)。 如果目錄下同時有 static 與 shared library 的話,,會以 shared 為主,。 $ gcc main.c -static -L. -lmylib 此時可以用 ldd 看編譯出的執(zhí)行檔與 shared 鏈接庫的相依性 因為編譯時有指定 -soname 參數(shù)為 libmylib.so.1 的關系,所以該執(zhí)行檔會加載 libmylib.so.1 ,。否則以 libmylib.so 連結(jié),,執(zhí)行檔則會變成要求加載 libmylib.so $ ./a.out 因為找不到 libmylib.so.1 所以無法執(zhí)行程序。 a. 把 libmylib.so.1 安裝到系統(tǒng)的 library 目錄,,如 /usr/lib 下 3. Dynamically loaded libraries Dynamicaaly loaded libraries 才是像 windows 所用的 DLL ,,在使用到 3.1 使用方式 ____ dltest.c ____ #include <dlfcn.h> int main() { /* 開啟之前所撰寫的 libmylib.so 鏈接庫 */ /* 取得 hello function 的 address */ 編譯時要加上 -ldl 參數(shù)來與 dl library 連結(jié) 關于 dl 的詳細內(nèi)容請參閱 man dlopen -- Creating a shared and static library with the gnu compiler [gcc] Program Library HOWTO APress - Definitive Guide to GCC ------------------------------------------------------------------------------------------------------------------ Makefile
clean: ------------------------------------------------------------------------------------------------------------------- |
|
來自: 心不留意外塵 > 《compile build》