大體上 c 程式構建過程可以分為預編譯、編譯、彙編以及鏈結四個過程。
庫的分類
備註優劣
static lib
將庫檔案與目標檔案在程式構建的鏈結階段鏈結在一起即靜態鏈結。
它的好處是程式執行不再依賴系統中存在這樣乙個庫檔案供呼叫,因為它已經在程式可執行檔案中了。缺點是如果同乙個庫被大量程式使用,那麼靜態鏈結將導致空間浪費、庫有問題修復需要所有使用該庫的程式重新編譯。
dynamic lib
動態庫的鏈結是在程式執行的時候被鏈結的。
動態庫的出現正彌補了靜態庫的以上弊端。劣勢是如果系統不存在程式所需的動態庫,那程式將無法執行。執行速度稍遜,但在如今的硬體能力面前不值一提,因此動態鏈結使用非常廣泛。
建立目錄如下:
.
├── main.c
├── makefile
└── so.c
// main.c
#include
extern
void
hello
(void);
intmain()
// so.c
#include
void
hello
(void
)// makefile
cc=aarch64-linux-gnu-
a.out: libso.so a_static.out main.c
$gcc main.c -lso -l.
-o $@
a_static.out: libso.a main.c
$gcc main.c -lso -l.
-o $@ -
static
libso.so: so.c
$gcc -shared so.c -o $@
libso.a: so.c
$gcc -c so.c -o so.o
$ar -r $@ so.o
.phony: clean
clean:
$-rf *
.so *
.a *
.out *
.o
在當前目錄下執行make
命令得到如下檔案。其中a_static.out
是通過與libso.a
靜態鏈結而來,a.out
是通過與libso.so
動態鏈結而來。
.
├── a.out
├── a_static.out
├── libso.a
├── libso.so
├── main.c
├── makefile
├── so.c
└── so.o
-l
提示 linker 尋找名為lib***.a
或lib***.so
的庫
-l
提示 linker 去哪些目錄下尋找-l
指定的庫
生成動態鏈結庫使用-shared
選項
生成靜態庫則使用ar
命令將.o
檔案打包即可。
把當前路徑加到/etc/ld.so.conf
中,然後執行ldconfig
以當前路徑為引數執行ldconfig
將當前路徑新增到環境變數ld_library_path
中,export ld_library_path=.:$ld_library_path
將動態庫拷到 /lib /usr/lib 路徑下,原因是作業系統缺省會從上述路徑中找動態庫
推薦使用方法3,即通過環境變數的方式來指定動態庫路徑,這樣影響最小。
這部分挖個坑,之後再談 ?。
靜態鏈結庫與動態鏈結庫的區別
靜態庫 函式和資料被編譯進乙個二進位制檔案 通常擴充套件名為.lib 在使用靜態庫的情況下,在編譯鏈結可執行檔案時,鏈結器從庫中複製這些函式和資料並把它們和應用程式的其它模組組合起來建立最終的可執行檔案 exe檔案 在使用動態庫的時候,往往提供兩個檔案 乙個引入庫和乙個dll。引入庫包含被dll匯出...
動態鏈結庫與靜態鏈結庫
有人會想,動態鏈結這樣麻煩,為什麼還要用呢?這裡有乙個技術問題,對這個問題的解決直接導致了動態載入的需求。問題是有些dll只在某個windows版本中存在,或某個api只在某些windows版本中被加入指定的dll。當你使用靜態鏈結的.exe試圖在不支援的windows版本上執行時,系統會彈出系統對...
動態鏈結庫與靜態鏈結庫
原貼出處 http blog.csdn.net benny5609 archive 2008 04 17 2298998.aspxs 還有參考 http msdn.microsoft.com zh cn library 1ez7dh12 v vs.100 aspxs 首先通過乙個簡單的靜態鏈結庫的例...