make整理

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在在第二階段展開

待補...

This entry was posted in Tips. Bookmark the permalink.

Leave a Reply