MakeFile從入門到精通 6

2021-09-19 14:53:28 字數 3986 閱讀 3187

庫的生成和使用

庫:其實就是目檔案的乙個歸檔,在前面我記得大致提過了乙個簡單介紹也記錄部落格了,可以返回去看看。目標檔案可以封裝成乙個庫。這裡我就學習如何使用命令把乙個原始檔封裝成乙個庫以及如何去使用。以及如何去編寫乙個makefile去生成庫和使用庫 。

先學習一下如何使用命令去生成乙個庫

編寫乙個helloc.c檔案內容下

1 #include2 

3 void hello()

4

執行 file   hello.o 可以檢視生成的hello.o是乙個重定位的檔案。

接著我們執行:ar   rcs    libhello.a    hello.o  //生成庫檔案  libhello.a

生成好這個庫檔案我們怎麼使用呢?

比如我們新增乙個main.c 內容如下:

1 #include2 void  hello();

3 int main()

4 5

**中我們先宣告了,helo()函式。後面就可以使用了,其實使用標頭檔案也可以,需要增加.h標頭檔案。

執行命令:gcc -m64  -o test  main.c -l ./   -lhello  //注意第乙個是 -大l   第2個是 -小l 後面是hello

-l  後面跟的是擴充套件路徑   -l後面跟的是擴充套件名字   -l小l可以取代lib這個字串。-小l 等於-libhello。

//注意我這裡是64位的ubbuntu 系統所以需要使用-m64, 可以檢視預設gcc 是32位還是64位。跟你的來。

我們執行  ./test

輸出:hello  main!

hello

下面演示一下在makefile裡面如何使用

定義乙個libmath.**件

1 #ifndef __libmath_h

2 #define __libmath_h

3 void libmath_init();

4 #endif

5

libgmath.c 檔案

1 #include 2 

3 void libmath_init()

4

makefile檔案

1 .phony:clean

2 3 libmath.a:libmath.o

4 ar rcs $@ $^

5 libmath.o:libmath.c libmath.h

6 clean:

7 rm libmath.a libmath.o

接著我們執行:make

輸出:cc    -c -o libmath.o libmath.c

ar rcs libmath.a libmath.o

檢視目錄下生成了libmath.a    libmath.o檔案

我們生成了 .a檔案後我們怎麼使用呢?

我們後退一級建立乙個test資料夾,並且拷貝libmath標頭檔案和libmath庫檔案 ,在裡面編寫乙個main.c檔案。

main.c

1 #include2 #include"libmath.h"

3 int main()

4

我們通過makefile使用庫檔案編譯。

mainfile

1 .phony: clean

2 3 hello:main.o

4 gcc -m64 -o $@ $^ -l./ -lmath

5 main.o:main.c

6 gcc -m64 -o $@ -c $^

7 clean:

8 rm hello main.o

可以看出makefile   ,main.o生成hello  ,接著下面就是用 -l  ./    -lmath使用的庫的名字新增進去。

執行make  輸出:

gcc -m64  -o main.o -c main.c

gcc -m64 -o hello main.o -l./ -lmath

執行 ./hello

hello world!

libmath_init ...

我們看看動態庫也是最常用的。庫格式檢視命令:objdump -p  libdll.so

編寫dll.h  dll.c  makefile

1 #ifndef __dll_h

2 #define __dll_h

3 void dll_init();

4 #endif

5

1 #include 2 

3 void dll_init()

4

1 .phony:clean

2 libdll.so:dll.o

3 gcc -m64 -o $@ -shared $^

4 dll.o:dll.c

5 gcc -m64 -o $@ -fpic -c $^

6 clean:

7 rm libdll.so dll.o

注意:生成.o檔案的時候  -fpic 引數就是生成 與位置無關的**,再生成.so的時候增加了 -shared引數生成共享庫。

動態庫是共享的,連線的時候不是載入到可執行檔案裡面的。它是單獨檔案形式可執行執行的時候動態庫載入到記憶體裡面的,所以我們需要這些引數。

我們執行:make

輸出:gcc -o dll.o -fpic -c dll.c 

gcc -o libdll.so -shared dll.o

同樣再上一級目錄建立乙個test資料夾,並且包括標頭檔案dll.h和庫檔案dll.so檔案。

main.c

1 #include2 #include "dll.h"

3 int main()

4

makefile

1 .phony:clean

2 hello:main.o

3 gcc -m64 -o hello main.o -l./ -ldll

4 main.o:main.c

5 gcc -m64 -o $@ -c -fpic $^

6 7 clean:

8 rm -f main.o hello

執行:make

輸出:gcc -m64  -o main.o -c -fpic main.c

gcc -m64 -o hello main.o -l./ -ldll

執行: ./hello

輸出:./hello: error while loading shared libraries: libdll.so: cannot open shared object file: no such file or directory

報這個錯誤。這是正常的這是載入共享庫它會根hello可執行程式一起載入記憶體。而我可執行程式會到系統指定的擴充套件庫去尋找庫的名字找不到就報這個錯誤。所以我們可以將這個so檔案拷貝到常用的庫路徑下面。類似win32需要拷貝dll到system32下面乙個道理。

我們執行拷貝命令:cp libdll.so   /usr/lib/

然後再執行:./hello

輸出:hello world!

dll_init ...

這時候就正確輸出。它就會去系統指定的路徑下去找。libdll.so的名字。

這就是動態庫與靜態庫不一樣的地方。

注意:windows下動態庫還可以與可執行行程式在乙個路徑也可以,但是linux下需要拷貝到系統的路徑。至於為什麼我也不知道。/use/lib/  下就可以了。

MakeFile從入門到精通 2

程式的編譯與連線 軟體的底層構造系統 1,程式儲存與執行 2,程式編譯和連線 3,程式檔案的分類 4,動態庫與靜態庫 計算機基本都遵循馮諾伊曼結構,cpu 記憶體ram ddr記憶體條 固態硬碟 嵌入式就是flash nor nand 一般手機平板呼叫 pc 伺服器基本都遵循。主要是這三塊組成。一般...

MakeFile從入門到精通 4

makefile 變數 變數在makefile中大量使用,使得makefile更加靈活功能更加強大。同時造成了讀makefile更加難讀。所以我們要發點時間學學變數。變數基礎 變數分類 變數追加,條件賦值 目標變數 模式變數 自動變數 系統環境變數 變數傳遞 一般在makefile裡面的變數都是存的...

Nginx從入門到精通

1 nginx配置檔案載入機制 採用nginx s reload命令載入nginx的配置檔案,master程序讀取配置檔案,建立新的worker程序,向老的worker程序傳送shutdown命令。老的worker程序不再接受新的請求,待老的請求處理完成後,就會停掉。2 location匹配機制 當...