Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Variables 立即进行变量赋值_Variables_Makefile - Fatal编程技术网

Variables 立即进行变量赋值

Variables 立即进行变量赋值,variables,makefile,Variables,Makefile,我在make文件中使用:=与用+=分配的变量组合时遇到了立即分配变量的问题。例如: VAR := a VARS += $(VAR) rule1: echo "$(VARS)" VAR := b VARS += $(VAR) rule2: echo "$(VARS)" 当我运行make时,不管规则如何,它都会打印“b”。我感到困惑的是,如果我使用以下make文件: VARS += a rule1: e

我在make文件中使用:=与用+=分配的变量组合时遇到了立即分配变量的问题。例如:

VAR := a
VARS += $(VAR)

rule1:
        echo "$(VARS)"

VAR := b
VARS += $(VAR)

rule2:
        echo "$(VARS)"
当我运行make时,不管规则如何,它都会打印“b”。我感到困惑的是,如果我使用以下make文件:

VARS += a

rule1:
        echo "$(VARS)"

VARS += b

rule2:
        echo "$(VARS)"
不管规则如何,它都会打印“a b”,这正是我所期望的。根据制造手册:

我们说,如果扩张发生在第一阶段,那么扩张是立竿见影的 阶段:在这种情况下,make将扩展中的任何变量或函数 作为makefile的构造部分被解析

立即的:=立即的

立即的+=延迟的或立即的

对于追加运算符“+=”,将考虑右侧 如果变量以前设置为简单变量,则立即 (“:=”或“::=”),否则延迟


如果:=实际上是立即变量,并且立即变量在解析时被展开,就像make手册所说的那样,那么我希望这些make文件具有相同的行为。为什么不是这样?我认为这要么是make文档中的错误,要么是make中的错误。

您缺少的一点是,配方行(规则体)在解析时没有展开(充其量只能部分展开,请考虑自动变量,例如
$@
$^
)而是在规则执行时展开

您在上面引用的手册章节的最后一节介绍了这一点:

规则定义

规则总是以相同的方式展开,无论其形式如何:

immediate : immediate ; deferred
   deferred
也就是说,目标和先决条件部分立即展开,用于构建目标的配方始终延迟。此一般规则适用于显式规则、模式规则、后缀规则、静态模式规则和简单的先决条件定义

因此,虽然您正确地认为作业是即时的,但您忽略了配方上下文中的扩展不是。因此,每次顶级作业完成后,食谱都会展开

此外,对于第一个示例,您从未将
VARS
设置为简单展开,因此在编写以下内容时,它默认为递归展开:

VAR := a
VARS += $(VAR)
并且认为你在做:

VAR := a
VARS += a
你不是

实际上,您正在执行字面上编写的操作,并将
$(VAR)
存储在
$(VARS)
的值中,这样,当make完成
$(VARS)
时,
$(VAR)
就成了
$(VAR)
,然后自然地扩展到
bb


如果你在第一个makefile示例的顶部添加
VARS:=
,你会得到你所期望的
ab
(从那时起,
VARS
被简单地展开,并在
+=
分配时间展开
$(VAR)

Etan的答案是正确的,但我认为不太符合目标。对于您明确的问题,非常简单的答案是,两个makefile具有不同行为的原因是
VARS
变量不是立即变量。
VAR
变量为,因为您将其设置为
:=
。但是,除非使用
+=
,否则永远不会设置
变量,并且默认的变量类型总是递归的(延迟的)。变量类型不是通过赋值继承的;将变量X设置为立即变量Y也不会使X立即生效。埃坦回答的最后一段,以及你上面引用的文件,是关键,我同意你的观点。将变量设置为:=是关键。@事实上,“问题”是对文档的误读和
VARS
变量的味道,但配方中扩展的延迟性质也是一个混淆因素。我对我的回答的评论也试图澄清这一点。这回答了问题,但规则的延迟属性不是问题所在,而是:=变量的初始化。现在我看到我误解了这句话:“对于append操作符,'+=',如果变量先前被设置为简单变量(':='或'::='),则右侧被视为立即变量,否则被延迟。”我认为它引用的变量是右侧的变量,但这是没有意义的,因为等式的右边不一定是一个变量。谢谢有两个问题。事实上,
VARS
并不是简单地扩展的,而且规则体是延迟的,不管它们包含的变量是什么。两者都在你所看到的令人困惑的结果中起了作用。但是,是的,误解正在讨论的变量是没有帮助的。