Linux下靜態庫學習筆記

2021-08-04 10:43:54 字數 4313 閱讀 9731

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 動靜之分是因為鏈結階段對庫的處理不一樣導致。程式編譯成可執行檔案的過程 預處理 編譯 彙編 鏈結 可執行檔案。靜態庫 在鏈結...