|
前言:編譯命令敲累了?是時(shí)候?qū)W點(diǎn)自動(dòng)化了!每次編譯項(xiàng)目是不是手動(dòng)敲gcc 命令? 當(dāng)項(xiàng)目文件一多,命令就像繞口令一樣——又長(zhǎng)又復(fù)雜,還特別容易出錯(cuò)。
別怕,今天我就帶你認(rèn)識(shí)一個(gè)“懶人神器”——Makefile。
用 Makefile 的好處很簡(jiǎn)單:
代碼編譯自動(dòng)化,輕松又高效;不用手動(dòng)敲命令,少掉坑;項(xiàng)目多大都不怕,它全能搞定。只要學(xué)會(huì)寫 Makefile,編譯這種枯燥的事情,再也不用你操心!讓我們從零開始,一步步帶你搞清楚它是啥、怎么寫,看完就能用!
1、什么是 Makefile?Makefile 就是一個(gè)編譯指揮官,你把編譯規(guī)則寫在里面,之后用一條簡(jiǎn)單的命令make,它就會(huì)按照規(guī)則自動(dòng)完成所有的編譯任務(wù)。
打個(gè)比方,你是項(xiàng)目經(jīng)理,Makefile 就是你的筆記本,記錄著項(xiàng)目的“施工計(jì)劃”:
每個(gè)目標(biāo)(比如可執(zhí)行文件main)的來(lái)源(哪些源文件);這些目標(biāo)要用什么命令生成;有哪些需要重復(fù)利用的部分(比如中間文件*.o)。一句話:Makefile 幫你自動(dòng)化處理那些又多又煩的編譯流程!
2、為什么用 Makefile?假設(shè)你有兩個(gè)源文件:main.c 和utils.c,手動(dòng)編譯步驟大概是這樣:先把main.c 和utils.c 分別編譯成目標(biāo)文件:[/ol]gcc -c main.c -o main.o
gcc -c utils.c -o utils.o 2. 再把目標(biāo)文件鏈接成可執(zhí)行文件:gcc main.o utils.o -o main
看著簡(jiǎn)單,但代碼一多,命令就會(huì)變成這樣:
gcc -c file1.c -o file1.o
gcc -c file2.c -o file2.o
gcc -c file3.c -o file3.o
...
gcc file1.o file2.o file3.o -o my_program
多打一條命令,多一個(gè)機(jī)會(huì)掉坑;一改代碼,又得全編譯一遍,時(shí)間都浪費(fèi)了。
用 Makefile,只需要:
make
一條命令,全搞定!而且它還會(huì)只編譯改動(dòng)的文件,效率直接起飛。
簡(jiǎn)單理解:
沒有 Makefile:自己手敲命令,累。有了 Makefile:只用一句make,剩下的事全自動(dòng)完成,爽。3、Makefile 的基本結(jié)構(gòu) (一分鐘搞懂)Makefile 是由一組規(guī)則(rule)組成的,每個(gè)規(guī)則都包含三部分:目標(biāo)(target):你想要生成的文件,比如main。依賴(dependencies):目標(biāo)文件需要哪些源文件或頭文件。命令(commands):生成目標(biāo)需要運(yùn)行的命令。[/ol]舉個(gè)例子:
main: main.o utils.o
gcc main.o utils.o -o main
main.o: main.c
gcc -c main.c
utils.o: utils.c
gcc -c utils.c
什么意思呢?
上面總共 3 條規(guī)則,來(lái)說(shuō)說(shuō)第一條規(guī)則:目標(biāo)是main,表示我們要生成一個(gè)叫main 的可執(zhí)行文件。依賴是main.o 和utils.o,也就是說(shuō)生成main 需要這兩個(gè)依賴文件先生成,而這兩個(gè)依賴是利用規(guī)則 2 和 規(guī)則 3 生成的。命令是gcc main.o utils.o -o main,它負(fù)責(zé)把.o 文件編譯成最終的可執(zhí)行文件。[/ol]后兩條規(guī)則類似,告訴make 怎么生成main.o 和utils.o。
簡(jiǎn)單嗎?這就相當(dāng)于告訴 Makefile:“你要先準(zhǔn)備好main.o 和utils.o,然后用 gcc 鏈接它們。”
4、Makefile 基礎(chǔ)功能:讓編譯自動(dòng)化從這里開始4.1 自動(dòng)生成目標(biāo)文件如果你每次都向上面一樣手寫main.o、utils.o 的生成規(guī)則,那 Makefile 就會(huì)變得非常繁瑣和重復(fù)。好消息是,Makefile 支持通配符,可以自動(dòng)生成規(guī)則!
%.o: %.c
gcc -c $ -o $@
這段代碼怎么用?假設(shè)你有main.c 和utils.c,Makefile 會(huì)自動(dòng)生成對(duì)應(yīng)的規(guī)則:
main.o:由main.c 生成,命令是gcc -c main.c -o main.o;utils.o:由utils.c 生成,命令是gcc -c utils.c -o utils.o。解釋一下符號(hào):
%.o 和%.c:% 是通配符,表示文件名匹配,比如main.o 和main.c。$:依賴文件,比如main.c。$@:目標(biāo)文件,比如main.o。用這個(gè)規(guī)則,Makefile 直接幫你生成所有目標(biāo)文件,舒服吧?
而當(dāng)項(xiàng)目文件越多,使用 Makefile 的優(yōu)勢(shì)就越大。
4.2 增量編譯:只編譯改動(dòng)的文件Makefile 有個(gè)超棒的功能:只編譯需要更新的文件。
它會(huì)檢查每個(gè)目標(biāo)的依賴文件,如果依賴文件沒有變化,就跳過(guò)編譯。
比如你改了main.c,Makefile 只會(huì)重新生成main.o,而utils.o 完全不動(dòng)。
這個(gè)功能在項(xiàng)目文件很多的時(shí)候,能節(jié)省一大堆時(shí)間。
4.3 清理臨時(shí)文件編譯后,會(huì)留下很多.o 文件和中間文件。Makefile 可以加一個(gè)clean 規(guī)則,幫你一鍵清理:
clean:
rm -f *.o main
直接運(yùn)行make clean,干凈清爽!
5、Makefile 的進(jìn)階玩法了解了基本用法后,咱們來(lái)看一些能提升開發(fā)效率的進(jìn)階功能。
5.1 基礎(chǔ)玩法 - 提高可讀性和可維護(hù)性1. 使用變量:讓 Makefile 更加簡(jiǎn)潔變量怎么使用?比如CC = gcc。變量可以讓 Makefile 更加靈活和易維護(hù)。
變量的基本用法:
# 定義變量
CC = gcc
CFLAGS = -Wall -g
TARGET = main
SRCS = main.c utils.c
OBJS = $(SRCS:.c=.o)
# $(SRCS:.c=.o) 是 Makefile 中的一種變量替換,它的作用是把變量 SRCS 中的每個(gè) .c 文件名換成對(duì)應(yīng)的 .o 文件名。
# 替換之后 OBJS = main.o utils.o
在命令中使用變量時(shí),需要用$() 的形式引用:
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(TARGET)
# 使用$()替換變量之后的規(guī)則如下:
main: main.o utils.o
gcc -Wall -g main.o utils.o -o main
這樣,如果你要修改編譯器或優(yōu)化選項(xiàng),只需要改動(dòng)變量部分,而不需要手動(dòng)修改每條規(guī)則。
2、偽目標(biāo):讓 Makefile 更靈活在 Makefile 中,有些目標(biāo)(比如clean)不會(huì)生成文件,而是用來(lái)執(zhí)行特定的命令,比如清理臨時(shí)文件。這種目標(biāo)我們稱為 偽目標(biāo)。
問(wèn)題來(lái)了:如果目錄中剛好有個(gè)文件名就叫clean,運(yùn)行make clean 時(shí),Makefile 會(huì)誤以為這個(gè)文件已經(jīng)存在,導(dǎo)致規(guī)則不執(zhí)行。
怎么解決?
用.PHONY 聲明偽目標(biāo),告訴make 這個(gè)目標(biāo)不是文件,應(yīng)該直接執(zhí)行命令。
示例:聲明偽目標(biāo)
.PHONY: clean
clean:
rm -f $(OBJS) $(TARGET)
這樣,即使目錄中有個(gè)名為clean 的文件,make clean 仍然會(huì)按規(guī)則執(zhí)行,刪除目標(biāo)文件和中間文件。
記。悍彩遣簧晌募哪繕(biāo),都建議用.PHONY 聲明!
5.2 進(jìn)階玩法 - 構(gòu)建更強(qiáng)大的 Makefile1、模式規(guī)則:適配更多文件類型有時(shí)候我們的項(xiàng)目里,不只有.c 文件,還有.cpp 文件。如果要分別寫規(guī)則,那就太麻煩了!這時(shí)候,模式規(guī)則 就能幫上大忙。
什么是模式規(guī)則?
模式規(guī)則就是一種通用規(guī)則,用來(lái)告訴 Makefile:
“遇到這種類型的文件,該怎么處理!
比如,告訴 Makefile:
.c 文件用gcc 編譯;.cpp 文件用g++ 編譯。這樣,Makefile 會(huì)根據(jù)文件后綴自動(dòng)選擇正確的規(guī)則,不用你手動(dòng)一個(gè)一個(gè)寫。
怎么用?支持 C++ 文件
假設(shè)項(xiàng)目里有.cpp 文件,我們可以加一個(gè)模式規(guī)則:
%.o: %.cpp
g++ -c $ -o $@
這樣,Makefile 會(huì)自動(dòng)把所有.cpp 文件編譯成.o 文件,完全不用你操心。
如何同時(shí)支持 C 和 C++ 文件?
如果項(xiàng)目里既有.c 文件,也有.cpp 文件,那我們可以寫兩條規(guī)則:
%.o: %.c
$(CC) $(CFLAGS) -c $ -o $@
%.o: %.cpp
g++ -c $ -o $@
這兩條規(guī)則的作用:第一條:告訴 Makefile,.c 文件用gcc 編譯。第二條:告訴 Makefile,.cpp 文件用g++ 編譯。[/ol]這樣,不管你的文件是.c 還是.cpp,Makefile 都會(huì)自動(dòng)搞定。
總結(jié)一下:
它會(huì)根據(jù)文件類型,自動(dòng)選擇合適的編譯方式;你只需要寫一條規(guī)則,Makefile 就能幫你搞定一大堆文件;再也不用重復(fù)寫規(guī)則了,省事又高效!記住:文件后綴不同?用模式規(guī)則全搞定!
2、條件語(yǔ)句:讓 Makefile 更聰明條件語(yǔ)句可以讓 Makefile 根據(jù)實(shí)際情況調(diào)整規(guī)則,比如不同的操作系統(tǒng)、不同的編譯模式,用起來(lái)既靈活又省心。
1、適配不同平臺(tái)
不同操作系統(tǒng)的命令可能不一樣,比如刪除文件,Linux 用rm,Windows 用del。通過(guò)條件語(yǔ)句,Makefile 可以自動(dòng)選擇正確的命令:
OS = $(shell uname)
ifeq ($(OS), Linux)
CLEAN_CMD = rm -f
else
CLEAN_CMD = del
endif
clean:
$(CLEAN_CMD) *.o $(TARGET)
在 Linux 上運(yùn)行make clean:執(zhí)行rm -f;在 Windows 上運(yùn)行make clean:執(zhí)行del。這樣,無(wú)論在哪個(gè)平臺(tái)都不用手動(dòng)改命令了,省事!
2、切換編譯模式
開發(fā)過(guò)程中經(jīng)常需要在調(diào)試模式(debug)和發(fā)布模式(release)之間切換:
調(diào)試模式:包含調(diào)試信息(方便排查問(wèn)題)。發(fā)布模式:優(yōu)化性能(適合生產(chǎn)環(huán)境)。用條件語(yǔ)句很容易實(shí)現(xiàn):
ifeq ($(MODE), debug)
CFLAGS = -g -O0
else
CFLAGS = -O2
endif
all:
$(CC) $(CFLAGS) -o $(TARGET) $(SRCS)
運(yùn)行調(diào)試模式:make MODE=debug
用-g 和-O0 編譯,生成帶調(diào)試信息的程序。
運(yùn)行發(fā)布模式:make
或:
make MODE=release
用-O2 編譯,生成優(yōu)化后的高性能程序。
小結(jié)一下:
適配不同平臺(tái): 條件語(yǔ)句讓 Makefile 在 Linux 和 Windows 上都能用。切換編譯模式: 方便開發(fā)階段調(diào)試和生產(chǎn)環(huán)境優(yōu)化。3、自動(dòng)化依賴管理: 讓 Makefile 更聰明!在寫代碼時(shí),.c 文件往往會(huì)用到頭文件.h。比如,你的main.c 里可能有一句:
#include "utils.h"
如果有一天你修改了utils.h,Makefile 怎么知道它需要重新編譯main.c 呢?
靠你手動(dòng)寫依賴規(guī)則?別開玩笑了,項(xiàng)目文件一多,光靠手動(dòng)寫依賴會(huì)把人累趴。
這時(shí)候,自動(dòng)化依賴管理就派上用場(chǎng)了。
什么是自動(dòng)化依賴管理?
自動(dòng)化依賴管理的核心是用gcc -M 命令,它能幫你自動(dòng)生成.c 文件和.h 文件的依賴關(guān)系。每次你修改頭文件時(shí),Makefile 會(huì)自動(dòng)觸發(fā)相關(guān)的.c 文件重新編譯。代碼怎么寫?
看下面這個(gè) Makefile 示例:
# 定義依賴文件列表
DEPS = $(SRCS:.c=.d)
# 生成 .d 文件,寫入依賴規(guī)則
%.d: %.c
$(CC) -M $ > $@
# 包含依賴文件
include $(DEPS)
它到底做了什么?定義依賴文件[/ol]DEPS = $(SRCS:.c=.d)
把源文件列表SRCS 中的每個(gè).c 文件,替換成對(duì)應(yīng)的.d 文件,比如:
main.c →main.dutils.c →utils.d這些.d 文件就是用來(lái)記錄.c 和.h 之間的關(guān)系。
2. 自動(dòng)生成依賴規(guī)則
%.d: %.c
$(CC) -M $ > $@
這條規(guī)則會(huì)用gcc -M 為每個(gè).c 文件生成一個(gè).d 文件,里面記錄了它依賴哪些頭文件。
比如,如果你的main.c 包含了utils.h,生成的main.d 文件可能是這樣的:
main.o: main.c utils.h3. 包含依賴規(guī)則include $(DEPS)
這句話告訴 Makefile,把所有.d 文件里的內(nèi)容加載進(jìn)來(lái)。每次運(yùn)行 Makefile 時(shí),它都會(huì)檢查.d 文件里的規(guī)則,看哪些文件需要重新編譯。
效果如何?
假設(shè)你有以下文件:
main.c 依賴utils.h;utils.c 不依賴任何頭文件。如果你修改了utils.h,Makefile 會(huì)自動(dòng)發(fā)現(xiàn)這個(gè)改動(dòng),然后只重新編譯main.c,而不會(huì)動(dòng)utils.c。
自動(dòng)化依賴管理的好處:再也不用手動(dòng)寫依賴規(guī)則,讓 Makefile 更智能;每次頭文件更新時(shí),Makefile 自動(dòng)判斷哪些文件需要重新編譯;即使項(xiàng)目文件多到爆,也能輕松應(yīng)對(duì)。[/ol]簡(jiǎn)單記。骸坝.h 文件,就用gcc -M 自動(dòng)生成依賴!”
4、多目標(biāo)支持:用 Makefile 管理多個(gè)模塊當(dāng)你的項(xiàng)目文件越來(lái)越多,甚至分成了多個(gè)模塊,比如lib 是核心功能模塊,app 是主程序模塊,光靠一個(gè) Makefile 已經(jīng)很難搞定了。
這時(shí)候,聰明的做法是:
每個(gè)模塊有自己的 Makefile,單獨(dú)管理自己的規(guī)則;用一個(gè)主 Makefile 調(diào)度所有模塊,讓項(xiàng)目更清晰、更高效!分模塊的做法:
1. 給每個(gè)模塊單獨(dú)寫一個(gè) Makefile
比如,在lib 模塊的目錄下,我們寫一個(gè)lib/Makefile:
# lib/Makefile
lib.a: lib.o # 定義目標(biāo) lib.a
ar rcs lib.a lib.o # 把 lib.o 打包成靜態(tài)庫(kù) lib.a
lib.o: lib.c # 編譯規(guī)則:生成 lib.o
gcc -c lib.c -o lib.o
lib.a 是靜態(tài)庫(kù),ar rcs 是打包命令。這個(gè) Makefile 只關(guān)心lib 模塊自己的文件,不影響其他模塊。2. 用主 Makefile 調(diào)度所有模塊
主 Makefile 位于項(xiàng)目根目錄,負(fù)責(zé)把所有模塊串起來(lái)。它并不關(guān)心每個(gè)模塊的具體規(guī)則,而是遞歸調(diào)用每個(gè)模塊自己的 Makefile:
# 主 Makefile
SUBDIRS = lib app # 定義模塊目錄
all: $(SUBDIRS) # 主目標(biāo):編譯所有模塊
$(SUBDIRS): # 遞歸調(diào)用每個(gè)模塊的 Makefile
$(MAKE) -C $@
clean: # 清理所有模塊
for dir in $(SUBDIRS); do $(MAKE) -C $$dir clean; done
代碼解釋:
1. SUBDIR 是模塊列表:這里定義了項(xiàng)目中的模塊,比如lib 和app。每個(gè)模塊目錄都有自己的 Makefile。
2. $(MAKE) -C $@ 是關(guān)鍵:這條命令的意思是切換到指定目錄(-C),然后運(yùn)行這個(gè)目錄里的 Makefile。比如,$(MAKE) -C lib 就是到lib 目錄運(yùn)行它的 Makefile。
[/ol]3. 遞歸清理 : clean 目標(biāo)會(huì)循環(huán)進(jìn)入每個(gè)模塊目錄,調(diào)用它們的clean 規(guī)則。注意$$dir 中的雙$,是為了讓 Makefile 能正確解析。
整體效果:
你可以在主目錄運(yùn)行make,它會(huì)自動(dòng)編譯所有模塊;運(yùn)行make clean 時(shí),它會(huì)遞歸清理所有模塊的臨時(shí)文件;每個(gè)模塊的規(guī)則獨(dú)立,清晰又方便維護(hù)。用主 Makefile 調(diào)度多個(gè)模塊的好處:結(jié)構(gòu)清晰:每個(gè)模塊的規(guī)則獨(dú)立管理,主 Makefile 只負(fù)責(zé)調(diào)度。易于維護(hù):修改或新增模塊時(shí),只需在SUBDIRS 添加對(duì)應(yīng)模塊目錄即可。高效遞歸:通過(guò)$(MAKE) -C 調(diào)用子目錄的 Makefile,模塊間互不干擾。[/ol]簡(jiǎn)單來(lái)說(shuō):分模塊管理,用主 Makefile 調(diào)度,一切井井有條!
5.3 高階玩法 - 優(yōu)化效率與靈活性1. 并行編譯:提高效率Makefile 的make 命令支持并行執(zhí)行多個(gè)規(guī)則,用-j 參數(shù)指定并行任務(wù)數(shù)。
示例:并行編譯
make -j4
這會(huì)同時(shí)運(yùn)行最多 4 個(gè)任務(wù),充分利用多核 CPU,顯著提升大項(xiàng)目的編譯速度。
2. 自定義函數(shù):復(fù)用邏輯在寫 Makefile 時(shí),如果規(guī)則中有重復(fù)的編譯邏輯,比如把.c 文件編譯成.o 文件,一直重復(fù)寫$(CC) $(CFLAGS) 就很麻煩。這時(shí)候,我們可以用自定義函數(shù)來(lái)統(tǒng)一管理這些重復(fù)操作,既方便又省事!
定義函數(shù):
用define 和endef 定義一個(gè)編譯函數(shù):
define compile
$(CC) $(CFLAGS) -c $ -o $@
endef
compile 是函數(shù)名,表示編譯的邏輯;$ 是依賴文件(比如main.c),$@ 是目標(biāo)文件(比如main.o)。使用函數(shù):
調(diào)用自定義函數(shù)時(shí),用$(call 函數(shù)名):
%.o: %.c
$(call compile)
這條規(guī)則會(huì)自動(dòng)把.c 文件編譯成對(duì)應(yīng)的.o 文件。
小結(jié)一下:自定義函數(shù)減少了重復(fù)代碼;修改邏輯時(shí),只需改函數(shù)定義,其他地方不用動(dòng);讓 Makefile 簡(jiǎn)潔易讀,清晰高效。[/ol]一句話:把重復(fù)的邏輯封裝成函數(shù),Makefile 也能優(yōu)雅起來(lái)!
3. 靜態(tài)模式規(guī)則:批量生成目標(biāo)文件當(dāng)多個(gè)文件需要用相似的規(guī)則編譯時(shí),一個(gè)個(gè)寫太麻煩,用靜態(tài)模式規(guī)則 就能一次性搞定!
先來(lái)看個(gè)簡(jiǎn)單示例: 假設(shè)我們要把多個(gè).c 文件編譯成.o 文件:
OBJS = main.o utils.o io.o
$(OBJS): %.o: %.c
$(CC) $(CFLAGS) -c $ -o $@
這是什么意思?
$(OBJS) 是目標(biāo)文件列表,比如main.o、utils.o;%.o: %.c 說(shuō)明每個(gè).o 文件由對(duì)應(yīng)的.c 文件生成;$ 是源文件(如main.c),$@ 是目標(biāo)文件(如main.o)。優(yōu)點(diǎn):減少重復(fù):一條規(guī)則批量處理,省時(shí)省力;自動(dòng)匹配:文件名自動(dòng)對(duì)應(yīng),無(wú)需手動(dòng)寫每條規(guī)則。[/ol]這里順便提下 通配模式規(guī)則,這兩種模式用法很相似。
對(duì)于更簡(jiǎn)單的項(xiàng)目,你可以用通配模式規(guī)則來(lái)實(shí)現(xiàn)類似效果:
%.o: %.c
$(CC) $(CFLAGS) -c $ -o $@
解釋一下:
每個(gè).o 文件由對(duì)應(yīng)的.c 文件生成;通配符% 會(huì)匹配任意文件名,比如main.c 自動(dòng)對(duì)應(yīng)main.o。靜態(tài)模式規(guī)則 vs. 通配模式規(guī)則
特性靜態(tài)模式規(guī)則通配模式規(guī)則匹配范圍針對(duì)特定目標(biāo)列表(如$(OBJS)
)自動(dòng)匹配所有符合%
的文件靈活性控制更精確,只處理指定的目標(biāo)文件簡(jiǎn)單統(tǒng)一,適合全局規(guī)則適用場(chǎng)景文件多、規(guī)則復(fù)雜,特定文件需要特殊處理文件少、規(guī)則統(tǒng)一,簡(jiǎn)單項(xiàng)目總結(jié):
通配模式規(guī)則適合簡(jiǎn)單項(xiàng)目,一條規(guī)則處理所有文件;靜態(tài)模式規(guī)則適合復(fù)雜項(xiàng)目,可以精確控制哪些文件應(yīng)用規(guī)則。記。汉(jiǎn)單全局用通配,精準(zhǔn)處理選靜態(tài)!
4. 跨平臺(tái)構(gòu)建:用 CMake 生成 Makefile如果項(xiàng)目需要在多個(gè)平臺(tái)(如 Windows、Linux、macOS)上編譯,直接寫 Makefile 會(huì)很麻煩。這時(shí),可以用 CMake 自動(dòng)生成適配不同平臺(tái)的 Makefile。
使用方法:
1. 創(chuàng)建 CMake 配置文件
在項(xiàng)目目錄下新建CMakeLists.txt,內(nèi)容如下:
# 聲明最低版本要求cmake_minimum_required(VERSION 3.10)
# 定義項(xiàng)目名稱project(MyProject)
# 指定可執(zhí)行文件add_executable(main main.c utils.c)2. 生成 Makefile
在終端運(yùn)行:
cmake .
3. 編譯項(xiàng)目
使用生成的 Makefile:
make
優(yōu)點(diǎn):
跨平臺(tái):適配 Windows、Linux、macOS 等操作系統(tǒng);簡(jiǎn)化管理:無(wú)需手寫復(fù)雜的 Makefile。一句話總結(jié):用 CMake 自動(dòng)生成 Makefile,跨平臺(tái)編譯就是這么簡(jiǎn)單!
五、完整示例結(jié)合前面學(xué)到的內(nèi)容,來(lái)看看一個(gè)完整的 Makefile:
# 定義變量
CC = gcc # 編譯器
CFLAGS = -Wall -g # 編譯參數(shù):開啟所有警告和調(diào)試信息
SRCS = $(wildcard *.c) # 獲取當(dāng)前目錄下所有的 .c 文件,并賦值給 SRCS 變量,例如:SRCS = main.c utils.c
OBJS = $(SRCS:.c=.o) # 把 .c 文件替換成 .o 文件,替換之后,OBJS = main.o utils.o
TARGET = main # 最終生成的可執(zhí)行文件
# 編譯規(guī)則
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(TARGET)
# 生成 .o 文件規(guī)則
%.o: %.c
$(CC) $(CFLAGS) -c $ -o $@
# 加上 .PHONY 聲明偽目標(biāo)
.PHONY: clean
clean:
rm -f $(OBJS) $(TARGET)
使用:
make:生成 可執(zhí)行文件main;make clean:會(huì)刪除所有.o 文件和可執(zhí)行文件main,保持項(xiàng)目目錄干凈。看了這篇文章,相信你看上面的 Makefile 代碼 應(yīng)該很輕松!六、寫在最后:從 Makefile 開始,走向編譯自動(dòng)化!Makefile 就是編譯中的“懶人神器”,一旦用上,你會(huì)發(fā)現(xiàn):
不再手動(dòng)敲命令,編譯變得更簡(jiǎn)單;即使項(xiàng)目越來(lái)越大,管理起來(lái)也毫不費(fèi)力;提高效率,節(jié)省時(shí)間,輕松搞定復(fù)雜編譯!如果你還在手動(dòng)敲命令,趕緊試試寫個(gè) Makefile,體驗(yàn)一下自動(dòng)化的快樂吧~
下篇文章我們將帶你進(jìn)入 CMake 的世界,了解如何跨平臺(tái)管理項(xiàng)目,敬請(qǐng)期待!
end
一口Linux
關(guān)注,回復(fù)【1024】海量Linux資料贈(zèng)送
精彩文章合集
文章推薦
?【專輯】ARM?【專輯】粉絲問(wèn)答?【專輯】所有原創(chuàng)?【專輯】linux入門?【專輯】計(jì)算機(jī)網(wǎng)絡(luò)?【專輯】Linux驅(qū)動(dòng)?【干貨】嵌入式驅(qū)動(dòng)工程師學(xué)習(xí)路線?【干貨】Linux嵌入式所有知識(shí)點(diǎn)-思維導(dǎo)圖 |
|