Linux庫檔案使用與編譯
阿新 • • 發佈:2018-11-09
介紹在Linux下使用靜態庫、共享庫、動態庫的方法。
Linux庫檔案
- 靜態庫
- 在Linux中,以.a為字尾,如
libtest.a
- 直接拷貝函式到二進位制映像檔案
- 只需要執行二進位制檔案,可以直接執行
- 在Linux中,以.a為字尾,如
- 共享庫
- 在Linux作業系統中,以
libxxx.so.x.x
為格式命名 - 可執行檔案在開始執行時將函式從共享庫檔案中讀出,從而間接引用
- 好處是,當函式介面沒變,實現改變時,不需要再次編譯
- 在Linux作業系統中,以
- 動態庫
- 動態載入庫在指定位置載入的函式庫
- 可以減少記憶體開銷
庫函式基本路徑
/lib
- 標準共享庫和靜態庫
/usr/lib
- 標準共享庫和靜態庫
/usr/local/lib
- 本地函式庫
庫檔案搜尋順序
- 首先在“LD_LIBRARY_PATH”環境變數所設定的路徑下查詢(一般都沒有給此環境變數賦值)
- 搜尋動態裝載器在/etc目錄下的快取檔案/etc/ld.so.cache(此檔案由命令ldconfig建立更新)。
ldd
命令–檢視到某可執行程式共享庫清單
建立靜態庫
-
libhello.c
libhello.h
為呼叫此庫檔案的標頭檔案,usehello.c
為測試程式。 -
首先將所需要檔案編譯成目標檔案
-
gcc -c libhello.c
-
-
使用
ar
命令建立靜態庫-
ar rc libhello.a libhello.o
-
-
編譯執行
-
gcc -o usehello_static usehello.c libhello.a
-
建立共享庫
-
首先將所需要的庫編譯成目的碼,這裡生成與位置無關,可以在任何地址被連結和裝載:
-
gcc -fPIC -Wall -g -c libhello.c
-
-
使用
-shared
來建立共享庫-
gcc -g -shared -Wl,-soname,libhello.so.1.0 -o libhello.so.1.0 libhello.o
-
這裡的
so.1.0
表示對應的完整版本號,具體可參考這裡。
-
-
建立
soname
連線:-
ln -sf libhelloso.1.0 libhello.so
-
這裡建立一個連結,只是為了方便以後版本更新時,只需要更改連結的路徑,不改變編譯程式碼
-
-
編譯並連線引用庫檔案
-
gcc -Wall -g -c usehello -o usehello.o gcc -g -o usehello_dynamic usehello.o -L ./ -lhello //連線引用庫檔案
-
其中,
-L
表示搜尋路徑,./
表示搜尋當前路徑 -
-lhello
- 會自動在
-l
前變為lib
,加上.so
,變為libhello.so
- 會自動在
-
-
執行,需要添加當前目錄
pwd
到環境變數中-
LD_LIBRARY_PATH=$(pwd) ./usehello_dynamic
-
-
如果希望在使用聯結器時不使用
-Ldirectory
標識就可以查詢到該庫,則可以採用以下方式之一:- 把此庫拷貝到/usr/lib或者/lib資料夾中,或者在此兩個資料夾任意一箇中建立一個到該庫的快捷方式,並命名為libname.so。
- 如果庫所在路徑沒有在/usr/lib和/lib資料夾下,需要將該路徑新增到檔案“/etc/ld.so.conf”中,每一行增加一個路徑,完成以上設定後,然後執行ldconfig命令更新庫資訊。
動態庫
-
在Linux中,動態庫的檔案格式跟共享庫沒有區別,主要區別在於共享庫是執行時載入。
-
有專門的一組API用於完成開啟動態庫,查詢符號,處理出錯,關閉動態庫等功能。
- dlopen
- dlerror
- dlsym
- dlclose
-
使用示例