make工具簡介

2022-03-13 04:43:00 字數 3335 閱讀 9984

在linux c/c++的開發過程中,當源**檔案較少時,我們可以手動使用gcc或g++進行編譯鏈結,但是當源**檔案較多且依賴變得複雜時,我們就需要一種簡單好用的工具來幫助我們管理。於是,make應運而生。

make主要用來管理c/c++專案,通過makefile書寫的規則來對專案中的源**檔案進行編譯,生成可執行的程式。

make執行的主要過程如下:當在shell中使用make命令時,make會尋找當前目錄下的makefile檔案,根據該檔案中的規則來確定依賴關係,如果乙個檔案所依賴的檔案比這個檔案要新,或者說修改時間更晚,那麼make會根據makefile中指明的命令來重新編譯生成該檔案。

另外,make除了自動尋找定義了編譯規則的makefile檔案外,還可以手動指明定義了規則的檔案。比如:

$ make -f rule.txt  # rule.txt中為make規則
makefile由一系列的規則構成,一條規則的基本格式如下:

目標 : 條件 

[tab] 命令

其中,需要在命令之前加乙個tab製表符,並且條件和命令都是可以省略的,但是只能省略其一,條件省略時一般做一些編譯以外的其他工作,當命令省略時其實也可以對目標進行編譯生成,這涉及到了makefile中的隱式規則,這裡不過多贅述,我們只討論顯式規則。

如make流程所述,當條件中的檔案比目標要新時,會執行tab後的命令。

makefile中有很多規則時,當在shell中執行make命令,缺省會將第一條規則的目標作為最終生成的目標。

比如下面這個makefile例子:

main: main.o sub.o

gcc -o main main.o sub.o

sub.o: sub.c sub.h

gcc -c -o sub.o sub.c

main.o: main.c sub.h

gcc -c -o main.o main.c

clean:

rm sub.o main.o

.phony: clean

當我們在shell中執行make時,會最終生成main這個最終目標。

但是如果我們只想生成某個中間的目標也是可以的,比如只生成sub.o,只需要採用make 最終目標的形式就可以了,即make sub.o

注意到示例中省略了條件的那條規則(目標為clean的那條規則),正規上把它叫做偽目標,用來執行一些其他的任務,如本例中清除編譯中生成的.o檔案。當然,偽目標下的命令可以是多種多樣的,比如將clean下的命令改為ls,當執行make clean時,會列出當前目錄下的所有檔案。但是有一點需要注意的是,如果我們的目錄下已經有了乙個叫做clean的檔案,當我們執行make clean時,make就分不清這個clean到底是那個了,為了避免這種情況,需要用.phony: 偽目標1,偽目標2..的方式來顯式的宣告偽目標。

當我們makefile中的規則變得非常多時,為了方便,也為了可維護性,我們一般使用變數來代替某些資訊。

makefile中定義變數的格式如下:

變數名 := 變數值
其中:=也該以使用=,依個人喜好。用$(變數名)的形式來使用變數。

先前示例中便可精簡如下:

cc := gcc

ld := gcc

cflags := -c

objs := main.o \

sub.o

main: $(objs)

$(ld) -o main $(objs)

sub.o: sub.c sub.h

$(cc) $(cflags) -o sub.o sub.c

main.o: main.c sub.h

$(cc) $(cflags) -o main.o main.c

clean:

rm $(objs)

.phony: clean

tip: 有時候我們的規則可能太長,寫在一行又不好看,可以使用\來進行換行。

makefile中還提供了一些內建變數,比如$(cc)代表預設的c編譯器,$(cxx)代表預設的c++編譯器。更多內建變數請參考這裡

makefile中還提供了一些特殊的變數,不用定義且會根據所在的規則而改變,減少一些目標檔名和條件檔名的輸入。以下是六個常用的自動變數:

變數名作用

$@

目標的檔名

$<

第乙個條件的檔名

$?

時間戳在目標之後的所有條件,並以空格隔開這些條件

$^

所有條件的檔名,並以空格隔開,且排除了重複的條件

$+

$^類似,只是沒有排除重複條件

$*

目標的主檔名,不包含副檔名

根據以上自動變數,我們可以將上面的示例改成更簡便的形式:

cc := gcc

ld := gcc

cflags := -c

objs := main.o \

sub.o

main: $(objs)

$(ld) -o $@ $^

sub.o: sub.c sub.h

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

main.o: main.c sub.h

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

clean:

rm $(objs)

.phony: clean

另外,儘管make工具常常用來管理c/c++專案,但是用來管理其他專案也是可以的,比如彙編專案,pascal專案,甚至是node.js的專案,make就是乙個工具,來幫我們管理一些構建的規則,只要規則寫的得當,怎麼用就隨你了。

最後,make雖然可以很好來管理專案了,但是還是不夠方便。試想一下,當makefile中的規則越來越多,又臭又長的時候,make就又顯得很難用了,這也就是為什麼cmake誕生的原因。通過編寫cmakelist,來指導cmake生成各種makefile檔案和project檔案,從而減輕管理makefile的負擔。

參考:

幾種make工具的區別

cmake cmake是乙個跨平台的安裝 編譯 工具,可以用簡單的語句來描述所有平台的安裝 編譯過程 他能夠輸出各種各樣的makefile或者project檔案。cmake 並不直接建構出最終的軟體,而是產生標準的建構檔 如 unix 的 makefile 或 windows visual c 的p...

make命令與Makefile檔案簡介

make工程管理,就是管理工程專案中的幾個檔案。大家在平時的練習中,編譯的檔案個數一般不超過五個,即使有幾個檔案進行了更改,也只需要對其重新編譯即可。但是工程若由成百上千個檔案組成,而只有其中個別檔案進行了修改,如果此時不知道哪幾個檔案被更改了,就只能用gcc把所有的檔案重新編譯一遍,這樣大大降低了...

linux 下面make工具的使用

在vs下面的工程檔案,光使用gcc命令已經很麻煩了,這時候就要用make命令,就像是乙個工程一樣,在vs下面微軟給我們做好了各種方便的用法,但是在linux下面就要靠我們自己寫了。使用make就一定要有個makefile,它描述了軟體包中各個檔案之間的關係,提供了更新每個檔案的命令。在乙個軟體包裡,...