Stop error when makefile rule target is foreach function

I have a makefile that defines several rules in which the target is a foreach function.

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

Is there a way to make make exit when it encounters an error without going through the whole list.

+9
source share
3 answers

foreach fully evaluated and replaced before any of the rules are followed. Thus, the behavior of this should be identical, as if you had hard-coded the rule without using foreach . In other words, this is not directly related to the problem.

There are only a few possible explanations for what you see, mostly described in the manual here :

  • You run Make with -k or --keep-going
  • You execute Make with -i or --ignore-errors
  • Your goals are defined as prerequisites for a special .IGNORE target
  • Your recipe starts with -
  • Your recipe does not actually return zero exit status
+8
source

One workaround is to manually call exit on error.

For example, suppose we have a directory called scripts with several shell scripts (with file names ending in .sh ) that we want to execute.

Then a variable declaration like this:

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

will give us a list of these scenarios and a goal similar to this:

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

it will run all of these scripts, but as you noticed, the foreach loop will continue to work regardless of whether one of the scripts returns an error code. Adding || exit || exit || exit || exit to the command will force the subcommand to terminate in the event of an error, which will then be considered an error.

For instance,

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

will do what you want (I believe).

In particular, using your pseudo-code example, I think you want something like this:

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

(where all I changed is the completion of the (CC) $(FLAGS)... bit (CC) $(FLAGS)... in the paren and adding || exit to fail on error).

+7
source

Not sure about your example, but there may be a problem in ; - look at Makefile: show and execute :

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

production:

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

So, make the exit code to check only for the last command: echo utils .

+3
source

Source: https://habr.com/ru/post/919291/


All Articles