• 正文
    • make?—— 項(xiàng)目的關(guān)節(jié)
    • 更進(jìn)一步
    • 結(jié)語(yǔ)
    • 參考資料
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

【LeafBuildTool】構(gòu)建工具系列1:make

02/11 22:00
886
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

make?—— 項(xiàng)目的關(guān)節(jié)

一個(gè)中型或大型項(xiàng)目,通常由許多文件組成模塊,又由各個(gè)模塊組成整個(gè)系統(tǒng),將各個(gè)文件、模塊構(gòu)建為系統(tǒng)的方式,一直是項(xiàng)目管理中的要點(diǎn)。make是一個(gè)傳統(tǒng)——但是流行的構(gòu)建工具,Makefile是其定義規(guī)則的文件,其中定義的規(guī)則就像關(guān)節(jié),將項(xiàng)目中的各部分靈活而有序地組織在一起。

基本語(yǔ)法

Makefile的核心是規(guī)則,其由一系列規(guī)則組成,每個(gè)規(guī)則的基本語(yǔ)法如下:

target:?prerequisites
????recipe
  • target:目標(biāo),即要?jiǎng)?chuàng)建或更新的文件,也可以是一個(gè)偽目標(biāo)(不對(duì)應(yīng)實(shí)際文件,用于執(zhí)行特定操作)。
  • prerequisites:依賴(lài)項(xiàng),是目標(biāo)所依賴(lài)的文件或其他目標(biāo)。當(dāng)依賴(lài)項(xiàng)中的任何一個(gè)發(fā)生改變時(shí),make會(huì)認(rèn)為目標(biāo)需要更新,并執(zhí)行對(duì)應(yīng)的規(guī)則命令。
  • recipe:規(guī)則命令序列,是為了創(chuàng)建或更新目標(biāo)而需要執(zhí)行的命令,必須以制表符(Tab)開(kāi)頭。

除此之外,Makefile還有一些作為腳本必要且實(shí)用的功能,以下的實(shí)際案例將進(jìn)一步說(shuō)明。

C語(yǔ)言項(xiàng)目構(gòu)建案例

CC?=?gcc
CFLAGS?=?-Wall?-g

all:?myprogram

myprogram:?main.o?utils.o
????$(CC)?$(CFLAGS)?-o?myprogram?main.o?utils.o

main.o:?main.c?utils.h
????$(CC)?$(CFLAGS)?-c?main.c

utils.o:?utils.c?utils.h
????$(CC)?$(CFLAGS)?-c?utils.c

clean:
????rm?-f?*.o?myprogram

以上Makefile編寫(xiě)了5條規(guī)則。

1. all

make默認(rèn)會(huì)執(zhí)行Makefile里首個(gè)規(guī)則的目標(biāo),此目標(biāo)通常被稱(chēng)作默認(rèn)目標(biāo)。一般而言,會(huì)把all作為默認(rèn)目標(biāo),該目標(biāo)依賴(lài)于項(xiàng)目中的其他主要目標(biāo),以此來(lái)確保所有必要的文件都能被構(gòu)建。

make也可手動(dòng)指定構(gòu)建目標(biāo),如:

make?all
make?clean
make?main.o

2. myprogram

myprogram目標(biāo)有2個(gè)依賴(lài)項(xiàng)main.outils.o,若依賴(lài)項(xiàng)已構(gòu)建完畢,則會(huì)執(zhí)行recipe部分所定義的命令,將.o文件通過(guò)gcc鏈接為可執(zhí)行文件myprogram

對(duì)于每個(gè)目標(biāo),make會(huì)檢查其依賴(lài)項(xiàng)是否存在或者是否有更新。若依賴(lài)項(xiàng)不存在,make會(huì)嘗試構(gòu)建這些依賴(lài)項(xiàng);若依賴(lài)項(xiàng)的修改時(shí)間比目標(biāo)新,make會(huì)認(rèn)為目標(biāo)需要更新,進(jìn)而執(zhí)行該目標(biāo)對(duì)應(yīng)的規(guī)則命令。

3. main.o

main.cutils.h文件有更新,則根據(jù)recipe定義的命令,通過(guò)gcc編譯生成main.o。

4. utils.o

main.o。

5. clean

目標(biāo)可以是文件,也可以是一個(gè)偽目標(biāo),偽目標(biāo)可通過(guò).PHONY聲明,確保即使存在同名文件,make也會(huì)執(zhí)行對(duì)應(yīng)的規(guī)則。(案例中由于不存在與目標(biāo)all/clean同名文件,故省略.PHONY聲明)

.PHONY:?all?clean

all:?myprogram
clean:
????rm?-f?*.o?myprogram

當(dāng)執(zhí)行偽目標(biāo)時(shí),make會(huì)直接執(zhí)行該目標(biāo)對(duì)應(yīng)的規(guī)則命令,而不會(huì)檢查文件的修改時(shí)間.

更進(jìn)一步

Makefile作為一種構(gòu)建腳本,可以像shell那樣,在recipe中直接編寫(xiě)命令,比如調(diào)用Python腳本。

CPython混合項(xiàng)目案例

假設(shè)項(xiàng)目中有一個(gè)C程序和一個(gè)Python腳本,C程序生成的數(shù)據(jù)會(huì)被Python腳本處理。

project/
├── main.c
├── process.py
└── Makefile
#?定義編譯器和編譯選項(xiàng)
CC?=?gcc
CFLAGS?=?-Wall?-g

#?定義目標(biāo)
all:?data.txt?result.txt

#?編譯?C?程序并生成數(shù)據(jù)文件
data.txt:?main
????./main?>?data.txt

main:?main.c
????$(CC)?$(CFLAGS)?-o?main?main.c

#?使用?Python?腳本處理數(shù)據(jù)文件
result.txt:?data.txt?process.py
????python3?process.py?data.txt?>?result.txt

#?清理生成的文件
clean:
????rm?-f?main?data.txt?result.txt

結(jié)語(yǔ)

Makefile還有一些常用的高級(jí)語(yǔ)法,后續(xù)有機(jī)會(huì)我會(huì)再開(kāi)一篇文章介紹。感興趣的朋友可以點(diǎn)贊支持哦~

參考資料

GNU make:?https://www.gnu.org/software/make/manual/make.html

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶(hù)資源
  • 寫(xiě)文章/發(fā)需求
立即登錄