gcc是linux中的編譯器,它是通過某種規則來進行編譯的,在這之前還有一個linux自帶的構建器叫make,make也需要通過某種規則來構建,而這些規則就通過makefile來設定。
makefile文件的命名可以是makefile或Makefile。
makefile中的規則
三部分:目標、依賴、命令
目標:依賴
(tab縮進)命令
app:a.c b.c c.c
gcc a.c b.c c.c -o app
makefile中由一條或多條規則組成。
makefile的工作原理
第一行的目標是做爲這個makefile要生成的最總目標,會依次檢測依賴是否存在,當依賴不存在,會向下搜索下邊的規則,如果有規則是用來生成查找的依賴的,執行規則中的命令;如果依賴存在,則會判斷是否需要更新該依賴,因爲目標的生成時間應該要比依賴的時間要晚纔對。例如:
app:a.o b.o c.o
gcc a.o b.o c.o -o app
a.o:a.c
gcc a.c -c
b.o:b.c
gcc b.c -c
c.o:c.c
gcc c.c -c
app依賴於三個.o文件,會依次查找依賴是否存在,當發現a.o不存在時,向下搜索到第二條規則,執行,生成a.o,其他兩個類似,然後在生成app;當對a.c文件進行修改後,a.o的生成時間將比a.c要早,再次執行make時會判斷時間,然後更新a.o,即再執行第二條規則。
makefile中的變量
以上的makefile的編寫顯得冗餘,可以用變量來改善:
makefile自帶的變量(都是大寫)
CPPFLAGS、CC等,這些變量有些已經被賦值,但還是可以用來賦值
自動變量
$@ : 規則中的目標
$< : 規則中的第一個依賴
$^ : 規則中所有的依賴
自動變量只能在規則中的命令中使用
修改上面的makefile
obj = a.o b.o c.o # makefile中的註釋用#號
target = app
$(target) : $(obj)
gcc $(obj) -o $(target) # gcc %^ -o $@
%.o : %.c
gcc -c $< -o $@
其中obj和target是自定義變量,值分別爲三個.o文件和要生成的目標文件,“$”符號表示去取變量的值;“%”是一個通配符,做模式匹配用,例如在第一次查找依賴a.o時,發現沒有,向下查找規則,%被替換成a,第二次查找b.o又被替換成b。
makefile中的函數
爲了使makefile在移植性方面做得更好,可以使用函數來改善,這是因爲makefile中的所有函數都是有返回值的。
查找指定目錄下指定類型的文件:
src = $(wildcard ./*.c) #當前目錄下的所有.c文件返回到src中。
匹配替換:
obj = $(patsubst %.c,%.o,$(src)) #將src中的.c替換成.o
再修改上面的makefile
src = $(wildcard ./&.c)
obj = $(patsubst %.c,%.o,$(src))
target = app
$(target) : $(obj)
gcc $(obj) -o $(target) # gcc %^ -o $@
%.o : %.c
gcc -c $< -o $@
清理項目
可以在makefile中添加清理項目的規則:
.PHONY clean
clean:
rm *.o $(target) -f #加上-f表示強制刪除
聲明僞目標
僞目標的用處在於不想讓make對目標做判斷是否是最新的,例如在文件夾下有文件名爲clean,但makefile中有clean規則,執行make clean時就會收到clean的影響,將clean聲明爲僞目標可以避免這種影響,方法是在clean規則上加上:
.PHONY clean