靜態庫和動態庫
靜態庫:
1. 編譯時連結;
2.浪費空間和資源,如果多個程式連結了同一個庫,則每個生成的可執行檔案就都會有一個庫的副本,必然浪費系統的空間;
3.若靜態庫修改了,需要重新進行編譯所有連結的程式
動態庫:
1. 執行時連結
2. 執行時被連結,程式執行速度稍慢
3.動態庫在程式執行時被連結,所以磁碟上只需要保留一份副本,因此節約磁碟空間。如果發現bug或者升級也很簡單,只需要用新的庫把原來的替換掉。
GCC編譯流程:
1.預處理:C/C++原始檔中,#開頭的命令都是預處理命令,包括標頭檔案,巨集定義以及條件編譯等。預處理就是將標頭檔案插入到原始檔中,把巨集定義展開,根據條件編譯選擇使用程式碼,最後這些程式碼輸出到.i檔案等待下一步處理。
gcc -E hello.c -o hello.i
2.編譯:將C/C++程式碼編譯成彙編程式碼
gcc -S hello.i -o hello.s
3.彙編:將編譯等到的檔案翻譯成一定格式的機器程式碼
gcc -c hello.s -o hello.o
4.連結:將上步生成的OBJ檔案和系統的OBJ檔案,庫檔案連結起來,生成可執行檔案。
gcc hello.o
靜態連結是在GCC編譯中連結時一起打包到可執行檔案;而動態庫在程式編譯時並不會連結導目的碼中,而是在程式執行時才載入。不同的應用程式如果呼叫相同的庫,那麼在記憶體中只需要有一份該共享庫的例項,規避了浪費空間的問題。動態庫是在程式執行時才載入,也解決了靜態庫對程式的更新,部署和釋出帶來的麻煩。使用者只需要更新動態庫即可。
生成靜態庫:
ar crv libfoo.a foo.c other.c
載入靜態庫:
g++ -o main main.cpp -L. -lfoo -static
生成動態庫:
g++ -o libshare.so -fPIC -shared share1.cpp share2.cpp
載入動態庫:
g++ -o main mian.cpp -L. -lshare
通過g++來指定路徑:
g++ -o main main.cpp -Wl,-rpath=./ -L. -lshare
-Wl,-rpath是用來指定動態庫的路徑
此外,動態庫指定路徑有以下幾種方法:
1.export更改LD_LIBRARY_PATH當前終端的環境變數
2.