linux下靜態庫、動態庫編譯及makefile書寫

在南京看海發表於2016-09-19

庫檔案原始碼為:app.c
使用庫檔案原始碼為:main.c


靜態連結庫生成:
gcc -c app.c
ar rcs libtest.a app.o
靜態庫檔名的命名規範是以lib為字首,緊接著跟靜態庫名,副檔名為.a。例如:我們要生成名為test的靜態庫,則靜態庫檔名就是libtest.a。
引數c: 選項意為只編譯不連結。
引數r:在庫中插入模組(替換)。當插入的模組名已經在庫中存在,則替換同名的模組。如果若干模組中有一個模組在庫中不存在,ar顯示一個錯誤訊息,並不替換其他同名模組。預設的情況下,新的成員增加在庫的結尾處,可以使用其他任選項來改變增加的位置。【1】
引數c:建立一個庫。不管庫是否存在,都將建立。
引數s:建立目標檔案索引,這在建立較大的庫時能加快時間。(補充:如果不需要建立索引,可改成大寫S引數;如果.a檔案缺少索引,可以使用ranlib命令新增)


靜態連結庫的使用:
g++ -o test main.c -L. -ltest
同樣使用靜態庫時,gcc會在靜態庫名前加上字首lib,然後追加副檔名.a得到的靜態庫檔名來查詢靜態庫檔案.


動態連結庫生成:
g++ -fpic -shared -o libtestshare.so app.c
動態庫檔名命名規範和靜態庫檔名命名規範類似,也是在動態庫名增加字首lib,但其副檔名為.so。
-fPIC 作用於編譯階段,告訴編譯器產生與位置無關程式碼(Position-Independent Code),不加fPIC編譯出來的so,是要再載入時根據載入到的位置再次重定位的.(因為它裡面的程式碼並不是位置無關程式碼),如果被多個應用程式共同使用,那麼它們必須每個程式維護一份so的程式碼副本了,我們總是用fPIC來生成so,也從來不用fPIC來生成a。
-shared 該選項指定生成動態連線庫。


動態連結庫的使用:
g++ -o test main.cpp -L. -ltestshare
gcc會在動態庫名前加上字首lib,然後追加副檔名.so得到的動態庫檔名來查詢動態庫檔案.
若找到,則載入動態庫,否則將提示類似上述錯誤而終止程式執行。通過修改 LD_LIBRARY_PATH或者/etc/ld.so.conf檔案來指定動態庫的目錄。通常這樣做就可以解決庫無法連結的問題了。


Ps:當靜態庫和動態庫同名時, gcc命令將優先使用動態庫

相關文章