GNU make:延迟构造的扩展

GNU make: expansion of a deferred construct

在包含描述 make 如何读取 Makefile 的文档的 this 网站上,有以下段落:

[...]

It’s important to understand this two-phase approach because it has a direct impact on how variable and function expansion happens; this is often a source of some confusion when writing makefiles. Here we will present a summary of the phases in which expansion happens for different constructs within the makefile. We say that expansion is immediate if it happens during the first phase: in this case make will expand any variables or functions in that section of a construct as the makefile is parsed. We say that expansion is deferred if expansion is not performed immediately. Expansion of a deferred construct is not performed until either the construct appears later in an immediate context, or until the second phase.

[...]

我不知道突出显示的部分是什么意思。

它是否试图说明如果在 deferred 部分首先找到一个变量引用,它不会在第一阶段展开,但如果随后找到相同的变量引用(稍后在Makefile) 在 immediate 上下文中,该变量引用将被扩展?为什么要明确的说这个?

或者它是否试图说明在某些情况下可以在不同的上下文中读取完全相同的行?

I do not know what the highlighted part means.

Does it try to say that if there is a variable reference first found in a deferred section it will not be expanded during the first phase, but if the same variable reference is then found (later in the Makefile) in an immediate context, that variable reference will be expanded?

好像是这样,但我犹豫要不要说"yes",因为我不确定我是否完全理解。相反,我用我自己的话来说:手册说,当一个表达式作为立即展开的表达式的值的一部分进行求值时,它会立即展开具有延迟展开的表达式。示例:

INTRO     := The messages are
DEFERRED   = $(MESSAGE1) literal message
IMMEDIATE := $(INTRO) $(DEFERRED)
MESSAGE1   = deferred message,

demo:
    @echo immediate: "$(IMMEDIATE)"
    @echo deferred: "$(INTRO) $(DEFERRED)"

演示:

$ make demo
immediate: The messages are  literal message
deferred: The messages are deferred message, literal message
$

请注意,变量 DEFERRED 作为设置立即扩展变量 IMMEDIATE 值的过程的一部分会立即扩展。您可以从两个 echo 命令的输出差异中看出这一点。您还可以看到,此扩展不符合 DEFERRED,这是令人困惑的事情之一。

Why would it say this explicitly?

因为人们可能会有不同的看法。具体来说,人们可能会假设在上面的示例中构建 "demo" 目标会导致打印两行相同的行。这将需要将 DEFERRED 的延迟扩展以某种方式符号化编码为 IMMEDIATE 的立即扩展,否则 DEFERRED 将以某种方式转换为立即扩展的变量。没有任何事情发生。

还要注意,DEFERRED 的两个扩展在这种情况下是不同的,这不一定是立即显而易见的可能性。

Or does it try to say that there are cases when the exact same line can be read within a different context?

因为我区分了 相同完全相同,唯一的方法是 "the exact same" 行可以在不同的上下文中进行评估如果它是延迟扩展表达式扩展的一部分。然后它可以出现在立即和延迟的上下文中,就像示例中的文本 $(MESSAGE1) literal message 一样。从这个意义上说,是的,手册正在谈论这一点;它与您的其他选择没有什么不同。

不同但相同的文本也可能出现在不同的上下文中,但这并不那么有趣。