makefile的展开分为一次展开和二次展开。一次展开发生在make的预处理阶段,此时只会展开目标、依赖的变量而不去展开命令中的变量,预处理阶段命令中的变量是没有上下文关系的。二次展开发生在make的运行阶段,解析展开所有命令中调用的变量。
由于命令只有在make运行时被解析,而某些命令中调用的变量依赖于其所处命令的上下文,因此我们需要避免命令中的这些变量被在预处理时展开。
举个例子:
(1)
main.c
Makefile
预处理阶段,DEP被call调用展开后,被eval当做独立的变量插入到makefile中。
其中,$$@和$$^在当前行中,被处理成$@和$^。
运行阶段,main的命令被执行,$@和$^被当前命令上下文识别为目标和依赖,make成功.。
make -n
(2)当我们把DEP中的$$改为$,$$@和$$^在预处理阶段,由于命令还没执行,$@和$^找不到对应上下文解析失败,则预处理后,main的规则变为:
main : main.o
gcc -o
make -n
因此,根据展开规则,为了避免在预处理阶段变量失效,我们将规则中所有依赖运行时命令上下文关系的变量全部用$$保护起来。










网友评论