GCC生成靜態庫.o以及動態庫.so檔案及其使用學習
編譯生成靜態庫檔案
1.編輯生成例子程式hello.h,hello.c,main.c
hello.c是函式庫的源程式,其中包括公用函式hello,該函式將在螢幕上輸出(hello XXX)
hello.h為該函式庫的標頭檔案,main.c為測試庫的主程式。在主程式中呼叫函式hello
程式1:hello.h
#ifndef HELLO_H
#define HELLO_H
void hello(const char*name)
#endif//HELLO_H
程式2 :hello.c
#include<stdio.h>
void hello(const char *name)
{
printf("Hello %s!\n",name);
}
程式3 :main.c
#include "hello.h"
int main()
{
hello("everyone");
return 0;
}
2,將hello.c編譯成.o檔案
無論是靜態庫還是動態庫都是由.o檔案建立的。因此,我們必須將源程式hello.c通過gcc先編譯成.o檔案
輸入命令 gcc -c hello.c
在資料夾中發現生成了hello.o檔案
3.由.o檔案建立靜態庫
靜態庫檔名命名規範是以lib為字首緊接著跟著靜態庫名,副檔名為.a。例如:我們將建立的而靜態庫命名為myhello,則靜態庫檔名就是libmyhello.a。在建立和使用靜態庫時我們需要注意這點,建立靜態庫用ar命令。在系統提示符下輸入以下命令建立靜態庫檔案libmyhello.a
#ar -crv libmyhello.a hello.o
4.在程式中使用靜態庫
靜態庫製作完了如何使用它內部的函式呢?
只需要在使用到這些公用函式的源程式中包含這些公用函式的原型宣告,然後再gcc命令生成目標檔案時指明靜態庫名字,gcc將會從靜態庫中將公用函式連線到目標檔案中注意gcc會在靜態庫名前加上字首lib,然後追加.a得到的靜態庫檔名來查詢靜態庫檔案。
在程式3:main.c中,我們包含了靜態庫的標頭檔案hello.h,然後在主程式main中直接呼叫公用函式hello.下面先生成目標程式hello,執行看看結果如何。
方式一:
gcc -o hello main.c -L. -lmyhello
方式二 :
gcc main.c libmyhello .a -o hello
方法三:
先生成main.o
gcc -c main.c
再生成可執行檔案
gcc -o hello main.o libmyhello.a
編譯建立動態庫檔案
動態庫檔案和靜態庫檔案命名方式類似,也是在名字前加字首lib,字尾便為.so,動態庫myhello檔名文libmyhello.so
建立動態庫檔案。
通過如下命令
gcc -shared -fPIC -o libmyhello.so hello.o-c
2.在程式中使用動態庫
使用命令
gcc -o hello main.c -L. -lmyhello
發現由於找不到動態庫檔案而出錯,程式執行時會在/user/lib和/lib中查詢需要的動態庫檔案,如果沒找到就會出現上述錯誤,現在將libmyhello.so複製到目錄user/lib中去
發現完美執行
探究
動態庫和靜態庫同名時會優先選擇哪個庫
將別的檔案刪除重新建立o和so 檔案
一開始會報錯,只有將庫檔案放於usr/lib中才可以執行所以同名的話會優先執行動態庫。
編寫一個簡單的例子程式按照上述方法編譯生成庫檔案,連線執行。
比較靜態庫和動態庫所生成的可執行檔案
main.c
sub1.h
sub1.c
sub2.h
sub2.c
1.通過gcc命令生成三個.o檔案
2.通過ar命令將sub1和sub2生成一個.a 靜態庫檔案。
3通過命令將main和庫檔案連結
檢視此可生成的檔案的大小等資訊。
4生成動態庫檔案並將其新增到usr/lib中,在通過命令將其連結生成可執行檔案
觀察其檔案大小可以發現大小略小於使用靜態庫生成的可執行檔案。