先说几件事:
.PHONY=a
什么都不做:变量.PHONY 并不特殊。要声明一个虚假目标,您需要将其列为.PHONY 伪目标的先决条件:
.PHONY: a
第二,这一行:
$(shell test -f $(1) || exit 1)
什么都不做:这里没有设置make变量$(1),所以test总是失败,但这没关系,因为退出代码被忽略了,见下文。
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 函数,该函数会立即停止 make,并打印该错误消息。