在Linux系統上,庫文件用于共享和重用代碼。根據使用方式和鏈接方式的不同,庫文件可以分為靜態庫和動態庫。
靜態庫(Static Library)
靜態庫是在編譯時被嵌入到最終可執行文件中的庫。靜態庫的擴展名通常是.a。
特點
- 獨立性:靜態庫在編譯時就被包含在可執行文件中,因此可執行文件獨立于庫的存在。
- 大小增加:由于靜態庫的代碼被直接復制到可執行文件中,最終的可執行文件大小會增加。
- 加載速度快:因為庫代碼已經在可執行文件中,不需要在運行時加載,啟動速度較快。
- 更新困難:更新靜態庫中的代碼需要重新編譯可執行文件。
創建靜態庫
1.編寫源代碼:
假設你有兩個源文件’foo.c’ 和 ‘bar.c’
foo.c:
// foo.c
#include <stdio.h>void foo() {printf("This is function foo.\n");
}
bar.c:
// bar.c
#include <stdio.h>void bar() {printf("This is function bar.\n");
}
2.編譯源文件:
使用 gcc 將源文件編譯為目標文件(.o 文件)。
gcc -c foo.c bar.c
這將生成 foo.o 和 bar.o 兩個目標文件。
3.創建靜態庫:
使用 ar 命令將目標文件打包成靜態庫。
ar rcs libmylib.a foo.o bar.o
這將創建一個名為 libmylib.a 的靜態庫文件。
使用靜態庫
1.編寫主程序:
創建一個使用靜態庫的主程序 main.c。
main.c:
// main.c
void foo();
void bar();int main() {foo();bar();return 0;
}
2.編譯并鏈接靜態庫:
在編譯主程序時鏈接靜態庫。
gcc -o myprogram main.c -L. -lmylib
其中,-L. 指定庫的路徑,-lmylib 指定鏈接的庫名(libmylib.a)。
3.運行程序:
執行生成的可執行文件。
./myprogram
輸出將會是:
This is function foo.
This is function bar.
動態庫(Dynamic Library)
動態庫是在運行時被加載的庫。動態庫的擴展名通常是.so(共享對象)。
特點
- 共享性:多個程序可以共享同一個動態庫,節省內存和磁盤空間。
- 可更新性:更新動態庫時,不需要重新編譯使用該庫的可執行文件,只需替換動態庫即可。
- 加載速度慢:在運行時加載動態庫,啟動速度可能比靜態庫稍慢。
- 依賴性:可執行文件依賴動態庫的存在和版本匹配,缺失或版本不匹配會導致程序無法運行。
創建動態庫
1.編寫源代碼:
假設你有兩個源文件’foo.c’ 和 ‘bar.c’
foo.c:
// foo.c
#include <stdio.h>void foo() {printf("This is function foo.\n");
}
bar.c:
// bar.c
#include <stdio.h>void bar() {printf("This is function bar.\n");
}
2.編譯源文件:
使用 gcc 將源文件編譯為位置無關代碼(Position Independent Code, PIC)的目標文件(.o 文件)。
gcc -fPIC -c foo.c bar.c
這將生成 foo.o 和 bar.o 兩個目標文件。
3.創建動態庫:
使用 gcc 將目標文件鏈接成動態庫。
gcc -shared -o libmylib.so foo.o bar.o
這將創建一個名為 libmylib.so 的動態庫文件。
使用動態庫
1.編寫主程序:
創建一個使用動態庫的主程序 main.c。
main.c:
// main.c
void foo();
void bar();int main() {foo();bar();return 0;
}
2.編譯并鏈接動態庫:
在編譯主程序時鏈接動態庫。
gcc -o myprogram main.c -L. -lmylib
其中,-L. 指定庫的路徑,-lmylib 指定鏈接的庫名(libmylib.so)。
3.設置庫路徑并運行程序:
在運行時,動態庫需要在系統的庫搜索路徑中,可以通過設置 LD_LIBRARY_PATH 環境變量指定路徑。
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
./myprogram
輸出將會是:
This is function foo.
This is function bar.
解釋 export LD_LIBRARY_PATH=.: $ LD_LIBRARY_PATH:
export:這是一個 shell 命令,用于設置環境變量,使其對后續的命令和腳本可見。
LD_LIBRARY_PATH=.:將當前目錄(. 表示當前目錄)添加到 LD_LIBRARY_PATH 中。這樣,系統會在當前目錄中查找動態庫。
:$LD_LIBRARY_PATH:將已有的 LD_LIBRARY_PATH 環境變量的值追加到新的 LD_LIBRARY_PATH 中。這保證了之前設置的搜索路徑不會丟失。