打包生成一個靜態庫&動態庫
阿新 • • 發佈:2019-01-10
靜態庫和動態庫之間不同之處就在於程式碼被載入的時刻不同。靜態庫的程式碼在編譯過程中已經被載入可執行程式,因此體積比較大;動態庫(共享庫)的程式碼是在可執行程式執行時被載入記憶體的,在編譯過程中僅簡單的引用,因此程式碼體積較小
一、靜態庫和動態庫的定義
1、靜態庫(.a)
程式在編譯連結的時候把庫的程式碼連結到可執行檔案中,程式執行的時候將不再需要靜態庫
下面打包實現一下靜態庫:
//add.h
#ifndef __ADD_H__
#define __ADD_H__
int add(int a, int b);
#endif //__ADD_H__
//add.c
#include "add.h"
int add(int a, int b)
{
return a+b;
}
//sub.h
#ifndef __SUB_H__
#define __SUB_H__
int sub(int a, int b);
#endif //__SUB_H__
//sub.c
#include "sub.h"
int sub(int a, int b)
{
return a-b;
}
//main.c
#include <stdio.h>
#include "add.h"
#include "sub.h"
int main()
{
int a = 2;
int b = 3;
printf("add(2,3)=%d\n", a, b, add(a,b));
a = 10;
b = 5;
printf("sub(10,5)=%d\n",a, b, sub(a,b));
}
* 注:(1) 由原始檔編譯生成一堆 .o檔案,每個 .o檔案裡都包含這個這個編譯單元的符號表
(2)ar命令將很多 .o轉換為.a,成靜態庫
(3)測試目標檔案生成之後,刪掉靜態庫,程式照樣可以執行
這樣打包使用靜態庫就完成啦!!!
庫搜尋路徑:
* 從左至右搜尋-L指定的目錄 * 由環境變數指定的目錄(LIBRARY_PATH) * 由系統指定的目錄>*/usr/lib>*/usr/local/lib
2、動態庫(.os)由gcc加特定引數編譯產生
程式在執行的時候才去連結動態庫的程式碼,多個程式共享使用庫的程式碼。動態庫檔名命名規範和靜態庫檔名命名規範類似,也是在動態庫名增加字首lib。
eg:建立的動態庫名為mymath,則動態庫檔名libmymath.so。
(1)由.o檔案建立動態庫檔案
// gcc -shared -fPCI -o libmymath.so math.o
shared:表示生成共享庫格式
fPIC:產生位置無關碼
(2)使用動態庫
// gcc main.o -o main -L. -l庫名
-l:連結動態庫,只要庫名即可
-L:連結庫所在的路程
3、靜態庫和動態庫的比較
因為靜態庫被連結後庫就直接被嵌入可執行檔案中了,這樣就會帶來以下幾個麻煩:
(1)系統空間被浪費,倘若多個程式連結同一個庫,則每一個生成的可執行檔案就都會有一個庫的副本,因此就會浪費系統空間。(2)當我們發現庫中有bug時,這就比較麻煩了,就要把連結該庫的程式都找出來,然後重新編譯
但是嘞,wuli動態庫就剛好巧妙的彌補了靜態庫的弊端。因為動態庫是在程式執行時被連結的,所以磁碟上必須保留一份副本,因此節約了磁碟空格。若果發現bug,我們只需用新的庫將原來的替換掉就可以了