gpt4 book ai didi

makefile - 如何获得 makefile 函数来停止当前目标?

转载 作者:行者123 更新时间:2023-12-04 13:23:03 25 4
gpt4 key购买 nike

我在 makefile 中有一个函数,如果文件不存在,或者至少不存在执行它的目标,我想停止整个 make 运行:

vaultfile = ./vault

$(shell test -f $(1) || exit 1)

define get_token
$(shell test -f $1 && cat $1 || exit 2)
endef

a: token = $(call get_token,$(vaultfile),tokenname)
a:
echo ==== $(token)
.PHONY=a

上面的方法不起作用,当文件丢失时静默失败

$ rm vault
$ make
echo ====
====
$ echo f > vault
$ make
echo ==== f
==== f

我希望它在函数中,因为大多数目标不调用该函数(这显然会执行更多 IRL)。

我如何使它工作?

最佳答案

首先是一些事情:

.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)

现在让我们看看调用扩展的结果是什么:

    echo ==== $(if $(wildcard ,/vault),`cat ./vault`,$(error File ./vault does not exist))

现在 make 评估 if 函数,条件是 wildcard 函数,如果它存在,它将扩展为 ./vault,并且如果没有,则为空字符串。 if 函数将非空字符串视为“true”,将空字符串视为“false”,因此如果文件存在,它将扩展为:

    echo ==== `cat ./vault`

如果文件不存在,它将运行 error 函数,立即停止 make,打印错误信息。

关于makefile - 如何获得 makefile 函数来停止当前目标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46816829/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com