linux下靜態庫學習筆記
1.什麼是庫
1-1.庫是一種軟體元件技術,庫裡面封裝了資料和函式。
庫的使用可以使程式模組化。
linux通常把庫檔案存放在/lib或/usr/lib目錄下。使用者建立的可以放在/usr/local/lib目錄下。
win32平台下,靜態庫通常字尾為.lib,動態庫為.dll。
linux平台下,靜態庫通常字尾為.a,動態庫為.so。
在程式中使用靜態庫和動態庫時,載入順序是不同的:靜態庫的**在編譯時就拷貝到應用程式中,動態庫為程式在開始執行後呼叫庫函式時才被載入。
1-2.靜態庫與動態庫的區別
1-2-1.利用靜態庫編譯成的檔案(空間)比較大,因為整個函式庫的所有資料都會被整合進目標**中,動態庫在編譯的時候並沒有被編譯進目標**中,因此動態庫所產生的可執行檔案比較小;
1-2-2.靜態庫在編譯後的執行程式不在需要外部函式庫的支援,而動態庫是程式執行時動態地申請並呼叫,所以執行環境中必須提供相應的庫;
1-2-3.如果靜態庫被改變,則程式必須重新編譯,動態庫的改變並不需要重新編譯程式,所以動態庫在公升級和維護上比較方便。
1-2-4.小結:
靜態庫:占用空間大,效率高,需重編
動態庫:占用空間小,效率低,不重編
1-3.靜態庫的建立和使用
1-3-1.基本步驟:
a.在標頭檔案中宣告靜態庫所匯出的函式
b.在原始檔中實現靜態庫所匯出的函式
c.編譯原始檔,生成目標**檔案
d.將目標**加入到靜態庫中
e.在程式中使用靜態庫
1-3-2.ar命令
ar命令用於建立靜態庫
格式:ar [-rcdtvs] lib***.a xx1.o xx2.o
選項r:在庫中插入模組(替換)。當插入的模組名已經在庫中存在,則替換同名的模組。預設情況下,新的成員增加在庫的結尾處,可以使用其他選項來改變增加的位置。
選項c:建立乙個庫。不管庫是否存在,都將建立。
選項d:刪除乙個模組。
選項t:輸出庫中包括的目錄(模組)。
選項v:顯示執行操作選項的詳細資訊。
選項s:建立目標檔案索引,這在建立較大的庫時能加快時間。
1-3-3.連線庫檔案的搜尋路徑
靜態庫鏈結時搜尋路徑順序:
a. ld會去找gcc命令中的引數-l
b. 再去找gcc的環境變數library_path
c. 再去找內定目錄/lib /usr/lib /usr/local/lib這是當初compile gcc時寫在程式內的
有關環境變數:
library_path環境變數:指定程式靜態庫鏈結庫檔案搜尋路徑
ld_library_path環境變數:指定程式動態庫鏈結庫檔案搜尋路徑
1-4.例項演練
1-4-1.編寫乙個靜態庫。
功能:輸出一條資訊hello jllee!
在程式中使用靜態庫函式。
1-4-1-1.建立標頭檔案head.h
#ifndef head_h
#define head_h
void printmessage();//函式的宣告
#endif //head_h
1-4-1-2.建立原始檔src.c
#include
#include "head.h"
int printfmessage()
1-4-1-3.編譯原始檔src.c,生成目標**src.o
gcc -c src.c
1-4-1-4.使用ar命令通過目標**src.o生成靜態庫libprintf.a
ar -rscv libprintf.a src.o
ps檢視庫包含什麼模組:ar -t libprintf.a
1-4-1-5.編寫程式main.c,使用靜態庫函式
#include
#include "head.h"
int main()
1-4-1-6.編譯程式main.c生成可執行程式test
gcc main.c -l. -lprintf -o test
ps –l.為指定靜態庫的路徑為當前路徑 –lprintf為指定程式要用到的庫
1-4-1-7.執行:./test
this is main function msg.
hello jllee!
1-4-2.多模組例子
1-4-2-1.建立原始碼add.c
int add(int a, int b)
1-4-2-2.建立原始碼sub.c
int
sub(int a, int b)
1-4-2-3.建立原始碼mutify.c
int mutify(int a, int b)
1-4-2-4.建立原始碼divide.c
#include
int divide(int a, int b)
else
return (a / b);
}
1-4-2-5.生成add.o divide.o mutify.o sub.o然後再生成libmath.a庫
a. gcc -c add.c sub.c mutify.c divide.c
b.先加入add.o模組:
ar -r libmath.a add.o
檢視libmath.a包含什麼模組:
ar -t libmath.a
add.o
c. 再加入divide.o模組:
ar -r libmath.a divide.o
檢視libmath.a包含什麼模組:
ar -t libmath.a
add.o
divide.o
d. 再加入mutify.o sub.o模組:
ar -r libmath.a mutify.o sub.o
檢視libmath.a包含什麼模組:
ar -t libmath.a
add.o
divide.o
mutify.o
sub.o
1-4-2-6. 1-4-2-5的操作可以使用萬用字元一次性生成add.o divide.o mutify.o sub.o跟libmath.a庫
gcc -c *.c
ar -r libmath.a *.o
1-4-2-7.編寫程式main.c,使用靜態庫函式
#include
int add(int , int);
intsub(int , int);
int mutify(int , int);
int divide(int , int);
int main()
1-4-2-8.編譯程式main.c生成可執行程式test
gcc main.c -o test -l. –lmath
1-4-2-9.執行:./test
10 + 2 = 12
10 - 2 = 8
10 * 2 = 20
10 / 2 = 5
1-4-3.搜尋路徑方法(gcc main.c -o test -lmath)
1-4-3-1.設定library_path環境變數的方法(編譯時不想要-l.選項)
a.先執行echo li
brar
ypat
h看看有
沒有內容
如果有:
則lib
rary
path
= library_path:.(在當前環境變數的前提下多加.當前目錄路徑)
如果沒有:則library_path=.(設定當前環境變數為.當前目錄路徑)
b.設定為環境變數declare -x library_path=.
或者export library_path=.:$library_path
取消環境變數unset library_path
c.編譯gcc main.c -o test -lmath
1-4-3-2.將建立的靜態庫放在預設的內定的任一目錄下
a.拷貝sudo cp libmath.a /usr/local/lib/
b.編譯gcc main.c -o test -lmath
Linux下靜態庫編譯
linux下動態庫檔案的擴充套件名為 so shared object 按照約定,所有動態庫檔名的形式是libname.so 可能在名字中加入版本號 這樣,執行緒函式庫被稱作libthread.so。靜態庫的檔名形式是libname.a。共享archive的檔名形式是libname.sa。共享arc...
linux下的靜態庫
linux下檔案的字尾名只是為了方便程式設計師知道這是什麼型別的檔案,不用來識別檔案型別。其中.so檔案 shared object 是動態庫 共享庫 相當於windows下的.dll a檔案是 archive 歸檔包 靜態庫 由多個.o檔案打包而來,相當於windows下的.lib o檔案是原始碼...
靜態庫 動態庫學習筆記
靜態庫 動態庫學習筆記 庫 是一種可執行 的二進位制形式,可被作業系統載入記憶體執行 是寫好的 現有的 完善的可複製的 庫可分為靜態庫 a或.lib 和動態庫 so或.dll 動靜之分是因為鏈結階段對庫的處理不一樣導致。程式編譯成可執行檔案的過程 預處理 編譯 彙編 鏈結 可執行檔案。靜態庫 在鏈結...