靜態連結庫在linux中間是以lib+name.a形式存在的,比如我們平時常用的printf函數,其具體實現在libc.a靜態庫中。在連結的時候,會將該庫函數裡面所有的內容插入到可執行檔中。
當程式連結完成後,就不再需要外部函數庫的支援了,因為調用的庫函數已經包含到可執行檔中了,缺點是產生的可執行程式的體積較大,而且當你的庫函數內容發生了變化的時候(比如對 庫函數進行了最佳化),又要重新進行編譯。
下面是我進行的一些編譯靜態庫函數的練習:
本程式需要編譯兩個靜態庫函數,libhello.a裡面有兩個函數,一個是int hello_world(),一個是int hello_tencent()。libprint_hello.a裡面有一個函數,int print_hello()。該函數調用了hello_world()和hello_tencent()。main.c中調用了print_hello();
vim hello.c
vim hello.h
vim print_hello.c
vim main.c
首先將hello.c編譯成靜態庫libhello.a
gcc -c hello.c
ar -cr libhello.a hello.o
c:表示create
r:表示replace,當需要插入的模組名已經在庫中存在的時候,替換掉同名的模組。
這樣,libhello.a就編譯好了
接著將print_hello.c編譯成靜態庫libprint_hello.a
gcc -c print_hello.c
ar -cr libprint_hello.a print_hello.o
在接著編譯main.c
gcc main.c -o main -L. -lhello -lprint_hello
但是此時會出現這樣的錯誤提示
因為print_hello.c裡面調用了hello.c裡面的函數,也就是說libprint_hello.a依賴libhello.a,所以需要將-lhello 和 -lprint_hello調換一下位置,最基礎的靜態函數放在最後面。
gcc main.c -o main -L. -lprint_hello -lhello
這樣就可以了
接著執行下程式./main
其編譯的Makefile如下:
vim Makefile: