在 C 語言中,代碼復用主要通過庫實現。靜態鏈接庫(Static Library)本質上是多個目標文件(.o)的歸檔集合,慣用後綴 .a(Linux/Unix)或 .lib(Windows)。鏈接階段,鏈接器將庫中所需的目標代碼直接複製到最終可執行文件中,形成「複製式鏈接」。
構建靜態庫不能用 tar,必須使用 GNU ar。它不僅歸檔,還會為符號建立索引表,加速鏈接查找。
rcsr:插入/替換模塊(同名則替換)c:創建庫(不存在則建立,不提示)s:創建/更新符號索引(大庫構建必備)補充:若庫缺少索引,可用 ranlib libxxx.a 事後添加;不需索引可用大寫 S。
// foobar.h
#ifndef _FOOBAR_H_
#define _FOOBAR_H_
#include <stdio.h>
extern char *foo(void);
extern char *bar(void);
#endif
// foo.c
#include "foobar.h"
char *foo(void) {
printf("This is foo! library2 is called!\n");
return "foo";
}
// bar.c
#include "foobar.h"
char *bar(void) {
printf("This is bar! library1 is called\n");
return "bar";
}
gcc -c foo.c -o foo.o
gcc -c bar.c -o bar.o
ar rcs libfoobar.a foo.o bar.o
nm libfoobar.a
# 輸出示例:
# foo.o: 0000000000000000 T foo
# bar.o: 0000000000000000 T bar
# T 表示符號在代碼段(文本段),為函數入口
// main.c
#include "foobar.h"
int main() {
foo();
bar();
return 0;
}
# 方式 1:顯式指定庫路徑與名稱
gcc -o foobar main.c -L. -lfoobar
# 方式 2:直接給庫文件路徑
gcc -o foobar main.c libfoobar.a
關鍵點: 靜態庫鏈接發生在編譯期,最終可執行文件不依賴庫文件即可獨立運行。
假設程序 A 和 B 都鏈接 libfoobar.a:
流程完全一致,僅替換工具鏈前綴:
arm-linux-gcc -c foo.c -o foo.o
arm-linux-ar rcs libfoobar.a foo.o bar.o
ldd foobar
# 輸出僅顯示系統動態庫(如 libc.so),無 libfoobar.a
# 證明靜態庫已內嵌,無運行時依賴
靜態庫是 C/C++ 模組化開發的基石,掌握其構建、鏈接與權衡,是構建高性能、易部署系統的關鍵能力。