文章目錄
一、概述
二、編寫
1)文件的命名規則
- makefile
- Makefile
2)用途
- 項目代碼編譯管理
- 節省編譯項目的時間
- 一次編寫終身受益
3)基本規則
目標:依賴
(tab)命令
- 目標 -->要生成的目標文件
- 依賴 -->生成目標文件需要的一些文件
- 命令 -->藉助依賴文件生成目標文件的手段
- tab -->縮進,有且只有一個
Makefile會把規則中的第一個目標作爲終極目標
- all:app -->all指定生成的最終目標爲app
4)工作原理
- 若想生成目標,檢查規則中的依賴條件是否存在,如果不存在,尋找是否有規則用來生成該依賴文件
- 檢查規則中的目標是否需要更新,必須檢查它的所有依賴,依賴中有任意一個被更新,則目標必須更新
- 依賴文件比目標文件時間晚,則需要更新
5)執行
- make -->通過 makefile 生成目標文件
- 直接 make(使用 makefile 文件)
- make -f mm(指定一個名字不爲 makefile 的文件)
- make clean -->清除編譯生成的中間 .o 文件和最終目標文件
- 如果當前目錄下有同名 clean 文件,則不執行 clean 對應的命令
- 解決方案 -->僞目標聲明。如:
.PHONY:clean
- 解決方案 -->僞目標聲明。如:
- 特殊符號
- -:表示此條命令出錯,make 也會繼續執行後續的命令。如:
-rm a.o b.o
- -:表示此條命令出錯,make 也會繼續執行後續的命令。如:
- 如果當前目錄下有同名 clean 文件,則不執行 clean 對應的命令
6)變量
- 普通變量
- 變量定義及賦值:
obj=a.o b.o c.o
- 變量取值:
foo=$(obj)
- 由 Makefile 維護的一些變量
- 通常格式都是大寫
- CC:默認值cc
- 有些有默認值,有些沒有
- CPPFLAGS:預處理器需要的選項 如:-I
- CFLAGS:編譯的時候使用的參數 -Wall -g -c
- LDFLAGS:鏈接庫使用的選項 -L -I
- 用戶可以修改這些變量的默認值
- CC=gcc
- 通常格式都是大寫
- 變量定義及賦值:
- 自動變量
- 變量
- $@ -->規則中的目標
- $< -->規則中的第一個依賴條件
- $^ -->規則中的所有依賴條件
- 模式規則
- 在規則的目標定義中使用%
- 在規則的依賴條件中使用%
- 實例:(%表示一個或多個)
-
%.o:%.c $(CC) -c $< -o $@
- $< -->表示依次取出依賴條件
- $@ -->表示依次取出目標值
-
- 變量
7)函數
- makefile中所有的函數必須都有返回值
- wildcard
- 查找指定目錄下指定類型的文件,一個參數
-
src=$(wildcard ./src/*.c)
- 找到 ./src 目錄下所有後綴爲 .c 的文件,賦給變量 src
- patsubst
- 匹配替換,從 sec 中找到所有 .c 結尾的文件,並將其替換爲 .o
-
obj=$(patsubst %.c,%.o,%(src))
- 把 src 變量中所有後綴爲 .c 的文件替換成 .o
-
ob=$(patsubst ./src/%.c,./obj/%.o,%(src))
- 指定 .o 文件存放的路徑 ./obj/%.o
三、實操
第一版makefile
第二版makefile
可以考慮編譯過程分解,先生成 .o 文件,然後使用 .o 文件變成結果
第三版makefile
定義變量
Makefile隱含規則:默認處理第一個目標
第四版makefile
函數
- wildcard:可以進行文件匹配
- patsubst:內容的替換
makefile變量
- $@: 代表目標
- $^ : 代表全部依賴
- $< : 第一個依賴
- $? : 第一個變化的依賴
第五版makefile
- 添加清理功能(@在規則前作用)
- “-”的作用就是,即使該條規則報錯,仍然繼續執行
- 防止有歧義, 定義僞目標
Final版makefile
# get all .c file
SrcFiles=$(wildcard *.c)
# all .c files ---> .o files
ObjFiles1=$(patsubst %.c,%.o,$(SrcFiles))
all:app.out
# 目標文件用法 $@: 目標;$<: 依賴
app.out:$(ObjFiles1)
gcc -o $@ -I./include $(ObjFiles1)
# 模式匹配規則, $@,$<這樣的變量,只能在規則中出現
%.o:%.c
gcc -c $< -I ./include -o $@
test:
@echo $(SrcFiles)
@echo $(ObjFiles1)
# 定義僞目標,防止有歧義
.PHONY:clean all
# 添加清理功能
clean:
-@rm -f *.o # 加 @表示指令不輸出
-@rm -f app.out