makefile: makefile, Makefile, GNUMakefile
一般結構採用top-down,從general寫到details
make -n 只印不執行,適合用在debug
make規則整理:
第一條rule為default rule (以cmake為例,第一條是 default_target: all)
rule分成target, prerequisite, command
target: prerequisites
command
prerequisite定義target的相依項目,command定義生成target
make解析順序: 對prerequsites recursive更新檢查,再對target更新檢查(如果prerequsites時間較新,則要重新生成target)
target因為是後生成,除非prerequsites有更新,不然一般要比prerequsites新
prerequisite: 除了檔案或是target,也可以是-lNAME (會搜索 libNAME.so => libNAME.a) 但一般不建議利用make來搜尋library是否存在,原因是通常在compiler選項會設定其他的library search path
target跟prerequisite比更新時間,
如果沒有prerequisite時,只有不存在target才會生成
同樣的target可以分開寫,會依序執行檢查
libname.a(module.o) lib target: ()是member
phony target: 可以想成代表command scripts的label,不對應檔案 (要標記 .PHONY)
.PHONY也是target的表示法,為special target(還有其他的sp target如.INTERMEDIATE
.SUFFIXES)
phony target 總是被執行(可想成總是outdated)
phony target作為prerequisite也會總是被執行
rule分成 explicit rules, pattern rules, implicit rules(built-in rules)
static pattern rules:
$(OBJECTS): %.o: %.c
對於$(OBJECTS)列出的檔案apply
.SUFFIXES know suffix (suffix rule會用到)
TAB: command以TAB起始
#: # 之後為註釋會被ignore,但注意command列中的#部會被忽略而會傳下去
\: line continuation
variable: case sensitive $(VAR) or ${VAR}, single character variable不用括號
variable naming convention: 代表command變數或環境變數全大寫, makefile的變數全小寫以 – 分隔
automatic variables
order is preserved (為了保留傳進去link order)
$@ target
$^ all prerequisites (duplicate filename removed)
$+ all prerequisites (duplicate filename reserved) <-為了lib link circular dependency
$< first prerequisite
$? prerequisites newer than the target (可用在update archive)
變數設定
lazy: VARIABLE = value (expand when variable is used)
immediate: VARIABLE := value (expand when variable is declared)
https://stackoverflow.com/questions/448910/what-is-the-difference-between-the-gnu-makefile-variable-assignments-a
variable可以來自: command line, Makefile, environment variables,
make CFLAGS=-g 會蓋過 Makefile內部assignment與環境變數
?= 方便用在處理外部設定變數並提供預設值
explicit rule -> implicit rule (make --print-data-base, make -p / 關掉--no-builtin-rules, make -R)
local directory -> VPATH
%在pattern中只能出現一次,代表word stem(至少一個字元)
gcc -M 產生Makefile可讀的 header dependency (automatic dependency generation)
-include (- 會 suppress warning) 常配合 .d的使用,因為一開始有可能depend file還沒有generate出來
macro定義
define this-is-macro-def
endef
$(this-is-macro-def)
macro使用時 command TAB會使macro內部所有列都apply
make執行時,分成兩階段,
第一階段是宣告期: 處理include並產生dependency graph
第二階段是執行期: 檢查必須要update的項目並執行command
deferred evaluation都是在第二階段
target, prerequisite 是第一階段展開,command script在在第二階段展開
待補...