1. 程式人生 > 其它 >gcc生成靜態庫、動態庫

gcc生成靜態庫、動態庫

0. 靜態庫.a和動態庫.so的區別:

靜態庫的程式碼在編譯過程中已經被載入可執行程式,因此體積比較大。
動態庫(共享庫)的程式碼在可執行程式執行時才載入記憶體,在編譯過程中僅簡單的引用,因此程式碼體積比較小。

1. 生成靜態庫:

假設有這樣一個cpp程式hello.c

#include "hello.h"
void sayhello()
{
  printf("hello,world ");
}
  1. 生成目標檔案hello.o:
gcc -o hello.o -c hello.c
  1. 使用ar(archive)將hello.o打包成libhello.a靜態庫
ar -rc libhello.a hello.o

解釋一下ar後帶的引數:
   -r :表示將.o檔案插入到.a中
   -c : 表示建立一個靜態庫檔案
   -d : 表示刪除這個靜態庫檔案
   -t : 表示列出.a檔案中所有成員

  1. 編譯main.c檔案並連結libhello.a
gcc -o app_static -c main.c libhello.a

2. 生成動態庫:

  1. 生成目標檔案hello.o:
gcc -fPIC -o hello.o -c hello.c //-fPIC 表示編譯為位置獨立(地址無關)的程式碼,不用此選項的話,編譯後的程式碼是位置相關的,所以動態載入時,是通過程式碼拷貝的方式來滿足不同程序的需要,而不能達到真正程式碼段共享的目的。
  1. 生成動態庫檔案hello.so
gcc -shared -o hello.so hello.o  //-shared 指定生成動態連線庫

1和2可以連在一起寫

ar -shared -fPIC -o hello.so hello.c
  1. 編譯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/

就表示搜尋標頭檔案從:/home/include/
--> /usr/include --> /usr/local/include

  1. 提一嘴:修改linux下動態庫的環境變數: LIBRARY_PATHLD_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