我在使用 := 与使用 += 分配的变量相结合的 make 文件中立即分配变量时遇到问题。例如:
VAR := a
VARS += $(VAR)
rule1:
echo "$(VARS)"
VAR := b
VARS += $(VAR)
rule2:
echo "$(VARS)"
当我运行 make 时,无论规则如何,它都会打印“b b”。我感到困惑的是,如果我使用以下 make 文件:
VARS += a
rule1:
echo "$(VARS)"
VARS += b
rule2:
echo "$(VARS)"
无论规则如何,它都会打印“a b”,这正是我所期望的。根据制作手册https://www.gnu.org/software/make/manual/html_node/Reading-Makefiles.html https://www.gnu.org/software/make/manual/html_node/Reading-Makefiles.html:
如果扩张发生在第一个阶段,我们就说扩张是立即的。
阶段:在这种情况下,make 将扩展中的任何变量或函数
解析 makefile 时构造的那部分。
立即 := 立即
立即 += 延迟或立即
对于追加运算符“+=”,考虑右侧
如果变量之前被设置为简单变量,则立即执行
(‘:=’或‘::=’),否则推迟。
如果 := 实际上是立即的,并且立即变量在解析时被扩展,正如 make 手册所说的那样,那么我希望这些 make 文件具有相同的行为。为什么事实并非如此?我相信这要么是 make 文档中的错误,要么是 make 中的错误。
您缺少的一点是配方行(规则主体)在解析时不会扩展(最多可以部分扩展,考虑一下自动变量,例如$@
and $^
例如),而是在规则执行时扩展。
这在您上面引用的手册部分的最后一部分中有介绍How make读取 Makefile http://www.gnu.org/software/make/manual/make.html#Reading-Makefiles:
规则定义
无论形式如何,规则始终以相同的方式扩展:
immediate : immediate ; deferred
deferred
也就是说,目标和先决条件部分立即展开,而用于构建目标的配方始终被推迟。此一般规则适用于显式规则、模式规则、后缀规则、静态模式规则和简单先决条件定义。
因此,虽然您认为分配是立即的,但您错过了配方上下文中的扩展is not。所以食谱是always扩大after每个顶级任务都已完成。
另外,对于第一个例子,你从未设置过VARS
作为简单扩展,因此它默认为递归扩展,因此当您编写时:
VAR := a
VARS += $(VAR)
并认为你正在做:
VAR := a
VARS += a
你不是。
你实际上是在做字面上写和存储的事情$(VAR)
的价值$(VARS)
这样当 make 完成时,值$(VARS)
is $(VAR) $(VAR)
然后,自然地扩展到b b
.
如果你添加VARS :=
在第一个 makefile 示例的顶部,您将得到a b
正如你所期望的(从那时起VARS
只是简单地扩展和扩展$(VAR)
at the +=
作业时间)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)