一、Makefile簡介
定義編譯規則、自動化編譯、提高效率組織文件
Makefile由一組規則(Rule)組成,每條規則的格式是:
例如:
依賴關係如下圖:
注意:
(1) 當我們爲了執行命令而非創建目標文件時,就會使用僞目標比如 clean,僞目標總是被執行。".PHONY" 的作用是避免和當前
目錄下的文件名衝突 (可能引發隱式規則)。
(2) 使用 "-" 前綴可以忽略命令錯誤,比如創建已有的路徑; “@” 可以不顯示命令本身
(3) Makefile 中 $、# 有特殊含義,可以進行轉義 "\#"、"$$"。
(4) 可以使用 \ 換行 (註釋行也可以使用),但其後不能有空格,新行同樣必須以 Tab 開頭和縮進。
(5) 在工作目錄按 "GNUmakefile、makefile、Makefile (推薦)" 順序查找執行,或 -f 指定。
(6) 如果不在 make 命令行顯式指定目標規則名,則默認使用第一個有效規則。
(7) 每條命令都在一個獨立 shell 環境中執行,如希望在同一 shell 執行,可以用 ";" 將命令寫在一行,也可用\ 換行。
(8) 在makefile 常見的gcc/g++參數 -D 即條件編譯; -static 使用靜態庫;注意 -L../lib -ldown 與 ../lib/libdown.so 等同
二、Makefile基本使用
make規則
沒被編譯過,則編譯;只編譯修改過的文件
頭文件被改變,只編譯包含該頭文件的文件
常用選項 : -C dir -f fileName -n 顯示待執行的命令,但不執行
Makefile組成
顯式規則:生成、依賴文件,生成命令
隱含規則:make支持的自動推導功能, make –p 打印
變量定義:類C中宏作用(?= := +=)。 引用方式 $(var) 或 ${var}。
"=" 遞歸展開變量,僅在目標展開時纔會替換,也就是說它可以引用在後面定義的變量。
":=" 直接展開變量,在定義時就直接展開,它無法後置引用。
"?=" 表示變量爲空或未定義時才進行賦值操作。
"+=" 追加賦值,也是遞歸展開
執行shell命令賦值給變量 A = $(shell uname)
文件包含:include
註釋: “#”
特殊變量:
三、Makefile 工作常用點補充
搜索路徑
VPATH 變量 VPATH = ./src : ./lib
vpath關鍵字(vpath<pattern> <directories> vpath %.h ../inc)
vpath %.c ./src : ./lib # 定義匹配模式(%匹配任意個字符)和搜索路徑。
vpath %.c # 取消該模式
vpath # 取消所有模式
VPATH 和 vpath 定義的搜索路徑僅對 makefile 規則有效,對 gcc/g++ 命令行無效,比如不能用它定義命令行頭文件搜索路徑參數。
變量引用與替換
obj=$(dir:%.c=%.o) 可以將變量 dir 中所有以 c 結尾的單詞替換成以 o 結尾
$(addprefix src/, foo bar) 返回值爲“src/foo src/bar”
src=$(wildcard *.c ./sub/*.c)
dir=$(notdir $(src))
obj=$(patsubst %.c,%.o,$(dir))
$(^D)
$(^F)
分別表示所有依賴文件的目錄部分和文件部分。(無相同的)
條件判斷
conditional-directive
text-if-true
else
text-if-false
endif
ifeq ($(CC),gcc) # 是否相等
ifdef CC # 變量是否定義
自動推導依賴關係
gcc –M main.c自動生成目標文件和源文件的依賴關係; -MM去除系統頭文件的依賴關係
maze.d,其內容是 maze.o maze.d:maze.c maze.h main.h