我最近使用Make时遇到了一些奇怪的行为(v3.81)。
假设我有以下Makefile:
FOOBAR = $(shell find nonexistentdirectory -iname "foobar" | tr '\n' ' ')
all:
@echo "Hi"
clean:
@echo "Hi again"
看起来很简单,对吧?值得注意的是,FOOBAR
是一个“递归扩展变量”,所以在我引用之前不应该对它进行评估。请注意,我从不提及它。另请注意,nonexistentdirectory
不存在,如您所料。
现在假设我在调用Make目标之前在shell 中设置FOOBAR
:
compy386$ FOOBAR="stuff" make clean
find: nonexistentdirectory: No such file or directory
Hi again
为什么评估FOOBAR
?显然,它与变量在shell中定义的事实有关。我是否应该预期用户可能在其shell中设置了变量?我在这里做错了什么?!
答案 0 :(得分:2)
FOOBAR
,因为您在clean
的条目中运行了一个配方(适用于FOOBAR
)和make
存在于环境中。由于FOOBAR
在条目中存在于环境中,因此它将成为导出变量,这意味着make
将其作为环境的一部分提供给配方中的任何程序。 make
不是特例echo
;它只是使用你路径中找到的那个。并且它无法知道该实用程序是否将引用特定的环境变量,因此它必须导出所有导出的变量,这意味着它必须评估FOOBAR
。
(官方消息,请参阅制作手册中Variables from the Environment的第3段。另请参阅recursive make invocation上的食谱。)
要回答直接问题,您可以告诉make
忽略变量来自环境的事实,以便它不会重新导出它,通过取消导出它:
unexport FOOBAR
答案 1 :(得分:0)
在?
之前添加=
,如:
FOOBAR ?= $(shell find nonexistentdirectory -iname "foobar" | tr '\n' ' ')
这将使用环境变量(如果已设置),仅在未设置或为空时进行评估。