Linux 編譯使用靜態庫
0 測試程序
-
目錄結構
-
include 存放頭文件
-
head.h
-
#ifndef __HEAD_H_ #define __HEAD_H_ int add(int a, int b); int sub(int a, int b); int mul(int a, int b); int div(int a, int b); #endif
-
-
-
src 存放源文件實現代碼
-
add.c
-
#include "head.h" int add(int a, int b) { int result = a + b; return result; }
-
-
div.c
-
#include "head.h" int div(int a, int b) { int result = a / b; return result; }
-
-
mul.c
-
#include "head.h" int mul(int a, int b) { int result = a * b; return result; }
-
-
sub.c
-
#include "head.h" int sub(int a, int b) { int result = a - b; return result; }
-
-
-
lib 存放生成庫文件
-
main.c 主程序入口
-
#include <stdio.h> #include "head.h" int main(void) { int sum = add(2, 24); printf("sum = %d\n", sum); return 0; }
-
-
1.1 靜態庫的基本概念
靜態庫是指在我們的應用中,有一些公共代碼是需要反覆使用,就把這些代碼編譯爲“庫”文件;在鏈接步驟中,鏈接器將從庫文件取得所需的代碼,複製到生成的可執行文件中的這種庫。(百度百科)
- Linux 下靜態庫的命名規則:
lib
+庫名字
+.a
。如:libMyCalc.a
1.2 靜態庫的基本製作流程
- 生成目標文件即
.o
文件:gcc -c *.c
- 將生成的
.o
文件打包:ar rcs 靜態庫名字(libMyCalc.a) *.o
- 將靜態庫文件和頭文件發佈即可
1.3 使用靜態庫
gcc main.c -Iinclude -Llib -lMyCalc -o myCalc
-I
:指定頭文件路徑-L
:指定庫文件路徑-l
:指定庫的具體名稱-o
:指定輸出文件的名字
1.4 靜態庫的優缺點
- 優點:
- 靜態庫直接加載到程序中,無需提供額外的庫文件
- 運行速度快,無庫加載過程
- 缺點:
- 由於將使用的庫文件編譯到程序中了,程序比較臃腫
2. Linux 編譯使用動態共享庫
2.1 動態共享庫的基本概念
程序編制一般需經編輯、編譯、連接、加載和運行幾個步驟。在我們的應用中,有一些公共代碼是需要反覆使用,就把這些代碼編譯爲“庫”文件;在連接步驟中,連接器將從庫文件取得所需的代碼,複製到生成的可執行文件中。這種庫稱爲靜態庫,其特點是可執行文件中包含了庫代碼的一份完整拷貝;缺點就是被多次使用就會有多份冗餘拷貝。
爲了克服這個缺點可以採用動態共享庫。這個時候連接器僅僅是在可執行文件中打上標誌,說明需要使用哪些動態連接庫;當運行程序時,加載器根據這些標誌把所需的動態連接庫加載到內存。(百度百科)
- Linux 下動態共享庫命名規則:
lib
+庫的名字MyCalc
+.so
2.2 動態共享庫的製作流程
- 生成位置無關的目標文件:
gcc -fPIC -c *.c
- 將位置無關的目標文件打包成共享庫:
gcc -shared -o libMyCalc.so *.o -I../include
2.3 使用動態共享庫
- 解決動態共享庫無法加載的問題
- 方案1:將自己生成的
.so
文件放到系統lib
庫目錄下,但是此類方法不推薦使用。 - 方案2:臨時使用
export LD_LIBRARY_PATH=/home/xxx/xxx
,關閉終端即失效 - 方案3:不常用方法,永久使用 修改家目錄下
.bashrc
文件,添加export LD_LIBRARY_PATH=動態庫絕對路徑
重啓終端生效 - 方案4:
- 找到動態連接器的配置文件:
/etc/ld.so.conf
- 動態庫的路徑寫到配置文件中 絕對路徑
- 更新**
sudo ldconfig -v
**
- 找到動態連接器的配置文件:
- 方案1:將自己生成的
- 動態共享庫使用:
gcc main.c -Llib -lMyCalc -o myCalc -Iinclude
2.4 動態共享庫優缺點
- 優點:使用動態共享庫的體積小,且多個程序可共享代碼,節省空間
- 缺點:加載動態共享庫需要時間消耗,且需要配置動態共享庫位置