我最近使用Make时遇到了一些奇怪的行为(v3.81).
假设我有以下Makefile:
FOOBAR = $(shell find nonexistentdirectory -iname "foobar" | tr '\n' ' ')
all:
@echo "Hi"
clean:
@echo "Hi again"
Run Code Online (Sandbox Code Playgroud)
看起来很简单吧?值得注意的是,它FOOBAR是一个"递归扩展变量",因此在我引用它之前不应该对它进行评估.请注意,我从不提及它.另请注意,nonexistentdirectory不存在您所期望的.
现在假设我FOOBAR 在调用Make目标之前设置了shell:
compy386$ FOOBAR="stuff" make clean
find: nonexistentdirectory: No such file or directory
Hi again
Run Code Online (Sandbox Code Playgroud)
为什么FOOBAR要评估?显然,它与变量在shell中定义的事实有关.我是否应该预料到用户可能在shell中设置了变量?我在这做错了什么?!
FOOBAR正在被评估,因为您正在运行一个配方 (for clean) 并且FOOBAR存在于进入 的环境中make。因为FOOBAR在进入时就存在于环境中,所以它成为导出变量,这意味着make它将作为环境的一部分提供给配方中的任何程序。make没有特殊情况echo;它只使用您路径中找到的那个。而且它无法知道该实用程序是否会引用特定的环境变量,因此它必须导出所有导出的变量,这意味着它必须评估FOOBAR.
(官方说法请参见 make 手册中环境变量的第三段。另请参见递归 make 调用的秘诀。)
要回答直接问题,您可以通过取消导出来make忽略变量来自环境的事实,以便它不会重新导出它:
unexport FOOBAR
Run Code Online (Sandbox Code Playgroud)