gcc生成靜態庫、動態庫
阿新 • • 發佈:2022-03-31
0. 靜態庫.a和動態庫.so的區別:
靜態庫的程式碼在編譯過程中已經被載入可執行程式,因此體積比較大。
動態庫(共享庫)的程式碼在可執行程式執行時才載入記憶體,在編譯過程中僅簡單的引用,因此程式碼體積比較小。
1. 生成靜態庫:
假設有這樣一個cpp程式hello.c
#include "hello.h"
void sayhello()
{
printf("hello,world ");
}
- 生成目標檔案hello.o:
gcc -o hello.o -c hello.c
- 使用ar(archive)將hello.o打包成libhello.a靜態庫
ar -rc libhello.a hello.o
解釋一下ar後帶的引數:
-r :表示將.o檔案插入到.a中
-c : 表示建立一個靜態庫檔案
-d : 表示刪除這個靜態庫檔案
-t : 表示列出.a檔案中所有成員
- 編譯main.c檔案並連結libhello.a
gcc -o app_static -c main.c libhello.a
2. 生成動態庫:
- 生成目標檔案hello.o:
gcc -fPIC -o hello.o -c hello.c //-fPIC 表示編譯為位置獨立(地址無關)的程式碼,不用此選項的話,編譯後的程式碼是位置相關的,所以動態載入時,是通過程式碼拷貝的方式來滿足不同程序的需要,而不能達到真正程式碼段共享的目的。
- 生成動態庫檔案hello.so
gcc -shared -o hello.so hello.o //-shared 指定生成動態連線庫
1和2可以連在一起寫:
ar -shared -fPIC -o hello.so hello.c
- 編譯main.c檔案並連結libhello.so
gcc -o app_shared main.c -L. -lhello
//或者直接寫出動態庫路徑
gcc -o main main.c ./libhello.so
解釋一下動態庫連結時後的引數:
-L : 指定編譯器在搜尋動態庫時搜尋的路徑,"."意思是當前路徑
-l (小寫l) :一般加庫檔名,即hello,如果在—L的路徑下找不到,就去LD_LIBRARY_PATH等環境變數的路徑下去查詢
-I (大寫i) : 指定路徑為首要路徑進去搜索標頭檔案,-I/home/include/
--> /usr/include --> /usr/local/include
- 提一嘴:修改linux下動態庫的環境變數: LIBRARY_PATH與LD_LIBPARY_PATH
LIBRARY_PATH:gcc編譯時查詢動態庫的指定存放路徑
LD_LIBPARY_PATH:程式執行載入時要查詢動態庫的指定存放路徑
export LIBRARY_PATH=/home/other/test/lib:$LIBRARY_PATH
export LD_LIBPARY_PATH=/home/other/test/lib:$LD_LIBPARY_PATH
如果不希望退出終端,這個新增路徑就失效,永久新增方法:
修改 ~/.bashrc或者系統下的/etc/profile
新增例如export LD_LIBRARY_PATH=/home/other/test/lib:$LD_LIBRARY_PATH
儲存,./bashrc