首先需要说明的几点:
.PHONY=a
没有任何作用:变量.PHONY
对于make来说并不是特殊的。要声明一个虚拟目标,您需要将其列为.PHONY
伪目标的先决条件:
.PHONY: a
第二,这一行代码:
$(shell test -f $(1) || exit 1)
不起作用:在此处未设置make变量$(1),因此测试始终失败,但这并不重要,因为退出代码被忽略,请参见下面的内容。
来自make shell函数的退出代码不会导致make失败,它会被忽略。要使make认为配方失败,必须使命令行本身以非零值退出。
一个很好的经验法则是,如果你发现自己在配方中使用make shell函数,那么你正在做错事情,并且你没有理解make如何扩展变量和函数。一个配方已经将被传递给shell,因此你根本不需要使用shell函数。
让我们看看在第一步扩展后,对于token变量,你的配方将是什么样子:
echo ==== $(call get_token,$(vaultfile),tokenname)
现在,当
call
函数被扩展后(请注意,函数的第二个参数
tokenname
完全被忽略),你会得到以下结果:
echo ==== $(shell test -f ./vault && cat ./vault || exit 2)
现在,make扩展了shell函数,该函数调用shell以运行命令并使用输出替换扩展...但忽略退出代码。假设
./vault
不存在:那么此shell命令不会输出任何内容,并且make将运行此规则:
echo ====
停止整个 make 运行的最佳方法是使用 error
函数。您可以使用 make 函数来完成所有工作,如下所示:
vaultfile = ./vault
get_token = $(if $(wildcard $1),`cat $1`,$(error File $1 does not exist))
a: token = $(call get_token,$(vaultfile),tokenname)
a:
echo ==== $(token)
让我们来看一下现在调用扩展的结果:
call
。
echo ==== $(if $(wildcard ,/vault),`cat ./vault`,$(error File ./vault does not exist))
现在,make评估
if
函数,条件是
wildcard
函数,如果存在,则会扩展为
./vault
,否则为空字符串。
if
函数将非空字符串视为“true”,空字符串视为“false”,因此如果文件存在,则会扩展为:
echo ==== `cat ./vault`
如果文件不存在,它将运行
error
函数,该函数会立即停止执行并打印错误消息。