今天在搞Makefile的时候掉进了一个大坑里,爬了好久。这里简单的笔记下Makefile的一些概念:
makefile中的“立即展开”与“延后展开”
本文参考【 http://blog.csdn.net/shyanyang/article/details/7529795 】
GUN make的执行过程分为两个阶段。
第一阶段:读取所有的makefile文件(包括“MAKEFILES”变量指定的、指示符“include“指定的、以及命令行选项“-f(–file)“指定的makefile文件),内建所有的变量、明确规则和隐含规则,并建立所有目标和依赖之间关系结构链表。
第二阶段:根据第一阶段已经建立的依赖关系结构链表决定哪些目标需要更新,并使用对应的规则來重建这些目标。
1.在make执行的第一阶段如果变量和函数被展开,那么称此展开是“立即“的,其他的展开称之为“延后“的。
2.变量定义解析规则如下:
IMMEDIATE = DEFERRED IMMEDIATE ?= DEFERRED IMMEDIATE := IMMEDIATE IMMEDIATE += DEFERRED or IMMEDIATE define IMMEDIATE DEFERRED Endef
当变量使用追加符 += 时,如果此前这个变量是一个简单变量(使用:=定义的)则认为它是立即展开的,其他情况时都被认为是“延后“展开的变量。
3.所有使用到条件语句在产生分支的地方,make程序会根据预设条件将正确的分支展开。即条件分支的展开是“立即“的。其中包括:“ifdef”、“ifeq“、”ifndef“和“ifneq“所确定的所有分支命令
4.所有的规则在make执行时,都按照如下的模式展开:
IMMEDIATE:IMMEDIATE;DEFERRED DEFERRED
注:上面的IMMEDIATE表示立即展开,DEFERRED表示延后展开
这里立即和延后的示例如下:
VAL1 = 1 VAL2 := 2 VAL3 = $(abspath .) VAL4 := $(abspath .) VAL5 = $(VAL3) VAL6 := $(VAL3) VAL3 = 3 SHOWARGS: @echo "VAL1: $(VAL1)" @echo "VAL2: $(VAL2)" @echo "VAL3: $(VAL3)" @echo "VAL4: $(VAL4)" @echo "VAL5: $(VAL5)" @echo "VAL6: $(VAL6)"
执行结果如下:
cstriker1407-T450-ubuntu:~/MakefileTest$ make VAL1: 1 #延后展开,但由于是简单变量,因此无所谓 VAL2: 2 #立刻展开,但由于是简单变量,因此无所谓 VAL3: 3 #延后展开,而且被改了值 VAL4: /home/cstriker1407/MakefileTest #立刻展开 VAL5: 3 #延后展开,VAL3的值改变会更新,即第一次展开为VAL5=$(VAL3), 第二次展开为VAL5=3 VAL6: /home/cstriker1407/MakefileTest #立刻展开,第一次展开为VAL6=/home/cstriker1407/MakefileTest,虽然后面VAL3被修改了,但是VAL6已经展开了,不会在变动
发表评论