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

ぐ巨炮叔叔 提交于 2021-01-28 19:19:06

问题


This question is a follow-up to What makefile lazy evaluation rule governs this behavior?. I'm still trying to grok some of the rules of gnu make's lazy evaluation.

I want to have a make variable for the content of a directory after that directory has been updated by a recipe.

This Makefile demonstrates that $(A_FILE) is evaluated to find the created file when it's in the "parent" of the recipe that actually creates the file:

A_FILE = $(wildcard subdir/*)

all: a
        @echo $(A_FILE)

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

But the following Makefile has a seemingly trivial change: $(A_FILE) is referenced in the recipe where its containing directory is updated - but now the variable is empty:

A_FILE = $(wildcard subdir/*)

all: a
        @echo $(A_FILE)

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


$ 

I added the sleep to rule out timing issues of the directory being trawled too quickly after it had been updated. What gives? Why does $(A_FILE) get evaluated against the updated subdir content if it's referenced in the higher-layer recipe but not in the lower-layer recipe where it's actually updated?


回答1:


GNU make evaluates all lines in the recipe before it starts running any line in the recipe. So, when it is getting ready to run your recipe for the rule a it first expands all the lines, including the last line with $(A_FILE) in it. At that point no parts of the recipe have been run yet so the result is empty.

Then after all the expansion, the shell is invoked to run the lines in the recipe.



来源:https://stackoverflow.com/questions/64084643/why-does-makefile-lazy-evaluation-find-a-file-in-a-parent-recipe-but-not-the-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!