当makefile规则的目标是foreach函数时停止错误

时间:2012-06-29 00:37:07

标签: makefile gnu-make

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

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

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

3 个答案:

答案 0 :(得分:8)

在执行任何规则之前,foreach已完全评估并替换。因此,这种行为应该与您在不使用foreach的情况下对规则进行硬编码相同。换句话说,它与问题没有直接关系。

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

  • 您正在使用-k--keep-going
  • 投放
  • 您正在使用-i--ignore-errors
  • 投放
  • 您的目标被定义为特殊.IGNORE目标
  • 的先决条件
  • 您的食谱以-
  • 开头
  • 您的食谱实际上并未返回非零退出状态

答案 1 :(得分:8)

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

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

然后是这样的变量声明:

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

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

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

将运行所有这些脚本,但正如您所注意到的,无论其中一个脚本是否返回错误代码,foreach循环都将继续运行。在命令中添加|| 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) ...位包裹在parens中并附加|| exit以使其在出错时失败。)

答案 2 :(得分:4)

不确定您的示例,但问题可能出在; - 请查看Makefile : show and execute

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