靜態連結庫的編譯與使用 linux下的動態連結庫和靜態連結庫到底是個什麼鬼?(一)靜態連結庫的編譯與使用
linux下的動態連結庫和靜態連結庫到底是個什麼鬼?(一)靜態連結庫的編譯與使用
知識不等於技術,這句話真的是越工作的時間長越深有體會,學習到的知識只有不斷的實踐,才成真正在自已的心裡紮下根,成為自身的一部分,所以無論如何,我希望我的部落格可以一直寫下去,慢慢的沉澱,終會有回報,無聊的時候想想,的確,寫程式碼也是一種自娛自樂!
前幾天在做專案時出了一個問題,大體就是:makefile裡在編譯可執行檔案testappd的時候在有用-l去引用一個libtest.so,能編譯通過,但是在載入執行的時候系統提示找不到這個lib而導致程序啟動失敗。後來知道在產品版本編譯打包的時候這個lib並未被打包進去,這個問題後來解決了。但是出於好奇,我想搞清楚動態庫和靜態庫的概念,以及之前做過另一個專案時以dlopen方式去引用動態庫和makefile 去引用動態庫這幾種方式的不同。查找了網上的一些資料,看明白了,還需手動驗證一下才放心。
首先說說靜態連結庫,說實話,有時候真心感覺計算機這些相關的各種高大上的詞彙都是紙老虎,看上去高深的不行,其實當你捅開那層紙,就那麼回事兒。
所謂靜態連結庫,說白了就是在你把寫好的程式碼編譯的時候,就把你引用的庫一起給編進去了,從此後你編出來的執行程式跟外面都不再有任何關係,即使這個庫更新了,你也搭不上邊兒,其次,如果系統中許多類似的程式都需要用到這個庫,那麼各自在編譯的時候都需要把這個庫給編進去,浪費儲存空間(載入到記憶體裡應該也是浪費記憶體空間的)。linux系統中靜態庫的名字一般叫
xxx.a, 所以如果你看到一個以 .a結束的檔案那麼它多半就是一個靜態連結庫檔案。
廢話少說,我們直接上乾貨,看看靜態庫是如何被編譯出來以及如何被使用的
首先我們寫了一個sum.c,如下,很簡單,裡面只有一個Sum函式,把兩個數相加的和返回
1 int Sum(int Number1, int Number2) 2 { 3 return Number1 + Number2; 4 }
當然還要寫一個宣告它的sum.h
int Sum(int Number1, int Number2);
最後來一個呼叫這個sum函式的主函式, 列印返回的結果
1 #include<stdio.h> 2 #include<sum.h> 3 4 void main() 5 { 6 int Num1 = 1; 7 int Num2 = 2; 8 int iRet = 0; 9 10 iRet = Sum(Num1, Num2); 11 printf("Num1 + Num2 = %d.", iRet); 12 return; 13 }
接下來我們編譯靜態庫,我的筆記本是mac os環境,開啟終端後用vim寫程式碼, gcc等相關工具直接就能用,版本沒注意,反正能用就行
1 192:zch kane$ ls 2 main.c sum.c sum.h 3 192:zch kane$ gcc -c sum.c 4 192:zch kane$ ls 5 main.c sum.c sum.h sum.o 6 192:zch kane$ 7 192:zch kane$ 8 192:zch kane$ ar cr libsum.a sum.o 9 192:zch kane$ ls 10 libsum.a main.c sum.c sum.h sum.o 11 192:zch kane$
如上,我們用ar這個工具來編譯靜態庫,cr標誌告訴ar將object檔案封裝
然後我們編譯主程式並執行:
192:zch kane$ gcc -o sumappd main.c -L . -lsum 192:zch kane$ ls libsum.a main.o sum.h sumappd main.c sum.c sum.o 192:zch kane$ ./sumappd Num1 + Num2 = 3
“-L .”指明瞭當前lib所在的路徑是在本目錄,-l表示連結libsum.a這個lib庫,很好理解。
知識不等於技術,這句話真的是越工作的時間長越深有體會,學習到的知識只有不斷的實踐,才成真正在自已的心裡紮下根,成為自身的一部分,所以無論如何,我希望我的部落格可以一直寫下去,慢慢的沉澱,終會有回報,無聊的時候想想,的確,寫程式碼也是一種自娛自樂!
前幾天在做專案時出了一個問題,大體就是:makefile裡在編譯可執行檔案testappd的時候在有用-l去引用一個libtest.so,能編譯通過,但是在載入執行的時候系統提示找不到這個lib而導致程序啟動失敗。後來知道在產品版本編譯打包的時候這個lib並未被打包進去,這個問題後來解決了。但是出於好奇,我想搞清楚動態庫和靜態庫的概念,以及之前做過另一個專案時以dlopen方式去引用動態庫和makefile 去引用動態庫這幾種方式的不同。查找了網上的一些資料,看明白了,還需手動驗證一下才放心。
首先說說靜態連結庫,說實話,有時候真心感覺計算機這些相關的各種高大上的詞彙都是紙老虎,看上去高深的不行,其實當你捅開那層紙,就那麼回事兒。
所謂靜態連結庫,說白了就是在你把寫好的程式碼編譯的時候,就把你引用的庫一起給編進去了,從此後你編出來的執行程式跟外面都不再有任何關係,即使這個庫更新了,你也搭不上邊兒,其次,如果系統中許多類似的程式都需要用到這個庫,那麼各自在編譯的時候都需要把這個庫給編進去,浪費儲存空間(載入到記憶體裡應該也是浪費記憶體空間的)。linux系統中靜態庫的名字一般叫
xxx.a, 所以如果你看到一個以 .a結束的檔案那麼它多半就是一個靜態連結庫檔案。
廢話少說,我們直接上乾貨,看看靜態庫是如何被編譯出來以及如何被使用的
首先我們寫了一個sum.c,如下,很簡單,裡面只有一個Sum函式,把兩個數相加的和返回
1 int Sum(int Number1, int Number2) 2 { 3 return Number1 + Number2; 4 }
當然還要寫一個宣告它的sum.h
int Sum(int Number1, int Number2);
最後來一個呼叫這個sum函式的主函式, 列印返回的結果
1 #include<stdio.h> 2 #include<sum.h> 3 4 void main() 5 { 6 int Num1 = 1; 7 int Num2 = 2; 8 int iRet = 0; 9 10 iRet = Sum(Num1, Num2); 11 printf("Num1 + Num2 = %d.", iRet); 12 return; 13 }
接下來我們編譯靜態庫,我的筆記本是mac os環境,開啟終端後用vim寫程式碼, gcc等相關工具直接就能用,版本沒注意,反正能用就行
1 192:zch kane$ ls 2 main.c sum.c sum.h 3 192:zch kane$ gcc -c sum.c 4 192:zch kane$ ls 5 main.c sum.c sum.h sum.o 6 192:zch kane$ 7 192:zch kane$ 8 192:zch kane$ ar cr libsum.a sum.o 9 192:zch kane$ ls 10 libsum.a main.c sum.c sum.h sum.o 11 192:zch kane$
如上,我們用ar這個工具來編譯靜態庫,cr標誌告訴ar將object檔案封裝
然後我們編譯主程式並執行:
192:zch kane$ gcc -o sumappd main.c -L . -lsum 192:zch kane$ ls libsum.a main.o sum.h sumappd main.c sum.c sum.o 192:zch kane$ ./sumappd Num1 + Num2 = 3
“-L .”指明瞭當前lib所在的路徑是在本目錄,-l表示連結libsum.a這個lib庫,很好理解。