linux下gcc程式設計03 make工程管理

2021-08-28 21:30:17 字數 4449 閱讀 1802

一。 make工程管理器簡介

工程管理器是指管理較多的檔案。如果有乙個上百個檔案的**構成的專案,

如果其中只有乙個或少數幾個檔案進行了修改,按照之前所學的gcc編譯工具,就不得不把這所有的檔案重新編譯一遍,

因為編譯器並不知道哪些檔案是最近更新的,而只知道需要包含這些檔案才能把源**編譯成可執行檔案,

於是,程式設計師就不能不再重新輸入數目如此龐大的檔名以完成最後的編譯工作。

編譯過程是分為編譯、彙編、鏈結不同階段的,其中編譯階段僅檢查語法錯誤以及函式與變數的宣告是否正確宣告了,

在鏈結階段則主要完成是函式鏈結和全域性變數的鏈結。因此,那些沒有改動的源**根本不需要重新編譯,而只要把它們重新鏈結進去就可以了。所以,人們就希望有乙個工程管理器能夠自動識別更新了的檔案**,同時又不需要重複輸入冗長的命令列,這樣,make工程管理器也就應運而生了。

實際上,make工程管理器也就是個「自動編譯管理器」,這裡的「自動」是指它能夠根據檔案時間戳自動發現更新過的檔案而減少編譯的工作量,同時,它通過讀入makefile檔案的內容來執行大量的編譯工作。使用者只需編寫一次簡單的編譯語句就可以了。它大大提高了實際專案的工作效率,而且幾乎所有linux下的專案程式設計均會涉及到它

1》makefile檔案

make在執行時,需要乙個命名為makefile或者makefile的檔案。makefile檔案描述了整個工程的編譯,鏈結等規則。

其中包括:1.工程中的哪些原始檔需要編譯以及如何編譯;

2需要建立哪些庫檔案以及如何建立這些庫檔案、

3如何最後產生我們想要的可執行檔案。

2》makefile語法

make通過定義規則來決定如何生成檔案

規則:用於說明如何生成乙個或者多個目標檔案,規則格式如下:

目標:依賴目標

(以tab空格)命令 比如

a:hello.c

gcc hello.c -o hello

a就是乙個目標名稱:hello.c就是目標依賴的檔案 這裡如果沒有依賴其他目標可以放置依賴的檔案

gcc hello.c -o hello 就是執行這個目標的命令 tab間隔隔開

在源**目錄新建makefile

a:hello.c

gcc hello.c -o hello

make編譯

[root@localhost vc]# make

gcc hello.c -o hello

3》多檔案的makefile依賴

假設有如下案例:

存在乙個公用的標頭檔案 a.h(用於定義全域性變數和 方法定義)

#include #include int add(int p1,int p2); //該方法在mmath.c中實現

void syso(char* c); //該方法在syso.c中實現

mmath.c實現add方法 內容如下:

#include "a.h"

int add(int p1,int p2)

syso.c實現syso方法

#include "a.h"

void syso(char* c)

main.c提供main方法入口 並且通過標頭檔案呼叫add方法獲取結果 呼叫syso輸出結果

#include "a.h"

void main()

我們知道main.c就是將來執行的程式的入口 如果直接編譯 main.c會出現沒有找到兩個方法實現錯誤

因為需要先生成mmath.o,syso.o,main.o 在進行鏈結生成最後的檔案

[root@localhost rule]# gcc main.c -o main

/tmp/ccowuqtm.o:在函式『main』中:

main.c:(.text+0x13):對『add』未定義的引用

main.c:(.text+0x3b):對『syso』未定義的引用

collect2: 錯誤:ld 返回 1

需要使用makefile檔案定義最後生成的程式目標需要依賴生成三個.o檔案的目標 

注意 make命令永遠只執行第乙個目標 如果這個目標依賴其他目錄 依賴的目標先被執行

m:a b c

gcc mmath.o syso.o main.o -o main

a: gcc -c main.c -o main.o

b: gcc -c mmath.c -o mmath.o

c: gcc -c syso.c -o syso.o

clean:

rm -rf *.o

執行(clean目標沒有被執行因為 不是第乙個目標 第乙個目標也沒有引用它 這種目標可以使用 make 目標名稱執行):

[root@localhost rule]# make

gcc -c main.c -o main.o

gcc -c mmath.c -o mmath.o

gcc -c syso.c -o syso.o

gcc mmath.o syso.o main.o -o main

執行 clean目標

[root@localhost rule]# make clean

rm -rf *.o

為了讓makefile檔案可讀性更好 建議目標 定義成生成的檔案  如果是編譯成目標檔案依賴目標寫成 原始檔 比如

main:main.o mmath.o syso.o

gcc mmath.o syso.o main.o -o main

main.o:main.c

gcc -c main.c -o main.o

mmath.o:mmath.c

gcc -c mmath.c -o mmath.o

syso.o:syso.c

gcc -c syso.c -o syso.o

.phony:clean #將「clean」目標聲稱為偽目標 不宣告也可以 make clean

clean:

rm -rf *.o

這樣做的好處就是 目標如何和命令輸出的檔名一致 在執行這個目標之前 判斷是否有這個檔案 有這個檔案 提示 不需要建立目標 比如  執行過一次  第二次執行 

[root@localhost rule]# make

make: 「main」是最新的。

makefile中可以定義變數 也可以使用系統變數 常用系統變數

$^ :代表所有的依賴

$*:代表所有的依賴 自動去掉字尾名

$@ :代表目標

$< :代表第乙個依賴

在每個目標中 命令中可以使用這三個變數 可以通過封裝的特點 減少重複**

main:main.o mmath.o syso.o

gcc $^ -o $@ #$^代表所有依賴也就是上面的main.o mmath.o syso.o $@代表目標也就是上面main

main.o:main.c

gcc -c $^ -o $@

mmath.o:mmath.c

gcc -c $< -o $@ #$《代表第乙個依賴 mmath.c 當然這裡就乙個依賴

syso.o:syso.c

gcc -c $^ -o $@

clean:

rm -rf *.o

上面的make中 gcc一旦修改 很多地方跟著修改 還可以定義一些自定義引數等 可以通過變數來定義 讓程式更優雅

cc=gcc

inclide=.

cflags=-g -wall -ansi -i$(inclide)

main:main.o mmath.o syso.o

$(cc) $(cflags) $^ -o $@

main.o:main.c

$(cc) $(cflags) -c $^ -o $@

mmath.o:mmath.c

$(cc) $(cflags) -c $< -o $@

syso.o:syso.c

$(cc) $(cflags) -c $^ -o $@

clean:

rm -rf *.o

在其他目錄 如果想直接某個目錄下的make檔案 可以使用 -c命令

表示進入 當前的hello目錄下 執行makefile 執行目標clean

[root@localhost vc]# make -c ./hello clean

make: 進入目錄「/root/vc/hello」

rm -rf hello

make: 離開目錄「/root/vc/hello」

linux下c程式設計起步學習 掌握gcc基本用法

初學時最好從命令列入手,這樣可以熟悉從編寫程式 編譯 除錯和執行的整個過程。編寫程式可以用vi或其它編輯器編寫。編譯則使用gcc命令。要往下學習首先就得熟悉gcc命令的用法。gcc命令提供了非常多的命令選項,但並不是所有都要熟悉,初學時掌握幾個常用的就可以了,到後面再慢慢學習其它選項,免得因選項太多...

linux下c程式設計起步 掌握gcc基本用法

初學時最好從命令列入手,這樣可以熟悉從編寫程式 編譯 除錯和執行的整個過程。編寫程式可以用vi vim 個人覺得vim比vi好用 或其它編輯器編寫。編譯則使用gcc命令。要往下學習首先就得熟悉gcc命令的用法。gcc命令提供了非常多的命令選項,但並不是所有都要熟悉,初學時掌握幾個常用的就可以了,到後...

linux下gcc命令筆記

首先介紹一下gcc各種引數的含義 o 指定生成的輸出檔案 e 僅執行編譯預處理 s 將c 轉換為彙編 wall 顯示警告資訊 c 僅執行編譯操作,不進行連線操作。1 gcc c fpic c 生成與位置無關的 o 檔案 目標檔案 fpic表明使用位址無關 2 gcc shared wl o libm...