为什么 makefile 惰性求值在 "parent" 配方中找到一个文件而不是当前的?

Why does makefile lazy evaluation find a file in a "parent" recipe but not the current one?

此问题是 的后续问题。我仍在尝试理解 gnu make 的惰性求值的一些规则。

我想在某个目录被配方更新后,为该目录的内容创建一个 make 变量。

这个 Makefile 演示了 $(A_FILE) 被评估以找到创建的文件,当它位于实际创建文件的配方的“父级”中时:

A_FILE = $(wildcard subdir/*)

all: a
        @echo $(A_FILE)

a:
        @mkdir ./subdir
        @touch subdir/b
$ rm -rf ./subdir/ && make
subdir/b
$ 

但是下面的 Makefile 有一个看似微不足道的变化:$(A_FILE) 在其包含目录更新的配方中被引用 - 但现在变量为空:

A_FILE = $(wildcard subdir/*)

all: a
        @echo $(A_FILE)

a:
        @mkdir ./subdir
        @touch subdir/b
        @sleep 1
        @echo $(A_FILE)
$ rm -rf ./subdir/ && make


$ 

我添加了 sleep 以排除目录在更新后被拖网过快的时间问题。 给出了什么?为什么 $(A_FILE) 会根据更新的子目录内容进行评估,如果它在较高层配方中被引用但在实际更新的较低层配方中没有被引用?

GNU make 在开始 运行ning any 行之前评估了配方中的 all 行。因此,当它准备好 运行 规则 a 的配方时,它首先展开所有行,包括其中带有 $(A_FILE) 的最后一行。那时食谱的任何部分都还没有 运行 所以结果是空的。

然后在所有扩展之后,shell 被调用到 运行 配方中的行。