Linux靜態庫和動態庫的命名規則和編譯連結
1、Linux靜態庫和動態庫的命名規則
靜態函式庫
靜態庫的名字一般是libxxx.a,利用靜態庫編譯生成的檔案比較大,因為整個靜態庫所有的資料都會被整合進目的碼中。
a)優點
編譯後,可執行檔案不需要外部支援;
b)缺點
生成的可執行程式大;靜態庫改變了,就需要重新編譯可執行程式。
動態庫函式
動態庫的名字一般是libxxx.so,相對於靜態庫,動態函式庫在編譯的時候並沒有被編譯進目的碼中,你的程式執行到相關函式時才呼叫函式庫裡面相應的函式,因此使用動態函式庫生成的可執行檔案比較小。由於函式庫沒有編譯進可執行程式,而是程式執行時動態的申請呼叫,所以程式的執行環境中必須提供相應的庫。動態函式庫的改變也不會影響可執行程式
優點
- 實現程序的資源共享,當程式在執行的時候需要呼叫某個動態連結庫函式時候,OS會先檢視所有正在執行的程式,看記憶體裡面是否已經有此函式的拷貝了,有責共享那個拷貝,沒有才會連結載入,這樣會大大節省OS的記憶體資源;
- 升級容易,升級動態連結庫即可,不需要重新編譯可執行程式;
2、gcc/g++的編譯連結:
通常,對函式的連結是在編譯期的時候完成的,所有相關的物件檔案與相關聯的library被連結成一個可執行檔案,這就是使用靜態庫的編譯過程,而動態庫技術:對一些庫函式的連結載入推遲到程式執行的時候。
但是,不管是使用靜態庫還是使用動態庫,這些庫檔案都是由*.o檔案生成的
靜態庫和動態庫的建立過程
a)建立靜態庫:
在linux環境下,建立靜態庫是使用ar命令,具體的選項可以man檢視下,例子:
//假如同目錄下有main.cpp,test.cpp,error.cpp三個檔案,執行如下
//生成.o檔案
g++ -c test.cpp error.cpp
//執行這步編譯生成test.o和error.o檔案
//生成靜態庫
ar -rt libtest.a error.o test.o
//使用靜態庫
g++ main.cpp -L./ -ltest -o main.exe
注意:
-L:指定靜態庫的搜尋路徑
-l:指定靜態庫/動態庫名稱,不需要攜帶字首lib和字尾.a或.so
b)建立動態庫:
使用gcc編譯.c檔案的使用,使用-fPIC標籤,然後在使用*.o檔案生成動態庫檔案的時候,傳遞-shared標籤給gcc,例子:
gcc –fPIC –c file1.c
gcc -fPIC -c file2.c
gcc –shared libtest.so file1.o file2.o
這樣就建立了libtest.so動態庫檔案。
使用靜態庫和動態庫的方法
動態庫檔案和靜態庫檔案的使用方法基本上差不多,在gcc的command裡面使用-Lpath和-lxxx標籤:
格式:gcc file1.o file2.o –Lpath –lxxx –o yourprogrammer
舉例:gcc file1.o file2.o –L./ –ltest –o test //test為可執行程式
編譯器會先到path下面尋找libxxx.so檔案,如果沒有找到,繼續尋找libxxx.a檔案。
那麼動態庫函式檔案,是在程式執行的過程中決定是否載入的,那麼我們需要告訴編譯器,去哪裡能找到動態庫函式檔案,在linux或者類unix作業系統裡面是使用LD_LIBRARY_PATH環境變數來實現的。