help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: foreach with error in loop continues


From: Paul Smith
Subject: Re: foreach with error in loop continues
Date: Mon, 10 Oct 2016 22:19:48 -0400

On Mon, 2016-10-10 at 13:50 -0700, Emmanuel Mayssat wrote:
> What I noticed is that if the loop fails ($? != 0), foreach still
> continues.

The loop body of a foreach loop cannot fail.  The foreach function (like
most functions in GNU make) doesn't actually run any commands: it
performs text substitution only.

For example the make invocation of:

  $(foreach x,a b c d e f,$x)

expands "$x" for each element in the loop, giving "a b c d e f".  It
doesn't try to "run" "$x" (whatever that might mean) and so there can be
no error code.

Likewise in your example:

> Here is the code:
> 
> define create_role_targets
> $(1):
>     -$(MAKE) -e IAM_ROLE_NAME=$(1) _iam_create_role
>     $(foreach P, $(call get_role_policies_R,$(1)), \
>         $(MAKE) -e IAM_POLICY_NAME=\$(P) -e IAM_ROLE_NAME=$(1) 
> _iam_validate_policy_document _iam_put_role_policies; \
>     )
> endef

This foreach loop _expands_ the text of its body completely, then the
results are passed to the shell, all at once.

Also, I don't know why you're passing the "-e" flag multiple times.  It
seems like you are under the impression you need to use it before every
variable assignment on the command line but that's not what -e means.

Also you don't escape dollar signs with backslashes inside make, you
escape them by writing two dollar signs "$$".

Let's look at a simpler example:

  POL = foo bar

  target:
          $(foreach P, $(POL), $(MAKE) X=y P=$(P) biz)

When make decides to build target it will first EXPAND the recipe, which
means the foreach loop.  The result of expansion will be this:

    make X=y P=foo biz make X=y P=bar biz

You can see immediately that is not what you want since it's just one
command, not multiple commands.  Also you can see that make isn't
running these commands during the foreach looping, so there's no chance
it can stop after the first one.

You can write your makefile like this:

  target:
          $(foreach P, $(POL), $(MAKE) X=y P=$(P) biz && ) true

Note how I added the "&&" to separate the commands.  The expansion of this 
which is passed to the shell will now be:

  make X=y P=foo biz && make X=y P=bar biz && true

This ensures that as soon as one of those make commands fails, the shell will 
exit immediately.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]