10

我有一个makefile,它定义了几个目标是foreach 函数的规则。

$(foreach var,$(list), $($(var)_stuff) $($(var)_more_stuff)):
    @echo Building $@ from $^...
    $(CC) $(FLAGS) ...

有没有办法让 make 在遇到错误而不遍历整个列表时退出。

4

3 回答 3

10

exit一种解决方法是在失败时“手动”调用。

例如,假设我们有一个目录,其中包含我们要执行scripts的许多 shell 脚本(文件名以 结尾)。.sh

然后是这样的变量声明:

LIST_OF_SCRIPTS ?= $(wildcard scripts/*.sh)

将为我们提供这些脚本的列表,以及这样的目标:

run-all-scripts
  @$(foreach scriptfile,$(LIST_OF_SCRIPTS),$(scriptfile);)

将运行所有这些脚本,但正如您所注意到的,无论其中一个脚本是否返回错误代码,foreach 循环都将继续进行。在命令中添加 a|| exit将强制子命令在出错时退出,然后 Make 会将其视为失败。

例如,

run-all-scripts
  @$(foreach scriptfile,$(LIST_OF_SCRIPTS),$(scriptfile) || exit;)

会做你想做的(我相信)。

具体来说,使用您的伪代码示例,我认为您想要这样的东西:

$(foreach var,$(list), $($(var)_stuff) $($(var)_more_stuff)):
    @echo Building $@ from $^...
    ($(CC) $(FLAGS) ...) || exit

(我所做的只是将(CC) $(FLAGS) ...位包装在括号中并附|| exit加以使其因错误而失败)。

于 2014-03-06T03:43:43.070 回答
10

在执行任何规则之前,它foreach会被完全评估和替换。因此,这种行为应该与您在不使用. 换句话说,它与问题没有直接关系。foreach

对于您所看到的内容,只有几种可能的解释,主要在此处的手册中进行了描述:

  • 您正在运行 Make-k--keep-going
  • 您正在运行 Make-i--ignore-errors
  • 您的目标被定义为特殊.IGNORE目标的先决条件
  • 你的食谱以-
  • 您的食谱实际上并未返回非零退出状态
于 2012-06-29T09:07:09.253 回答
6

不确定您的示例,但可能问题出在;- 查看Makefile :显示并执行

dirs = $(shell ls)
clean:
    $(foreach dir,$(dirs),echo $(dir);)

生产:

$ make clean
echo bin; echo install.sh; echo Makefile; echo README.md; echo utils;

所以只检查最后一个命令的退出代码:echo utils

于 2013-07-23T10:11:54.267 回答