help-make
[Top][All Lists]
Advanced

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

Re: Is it possible to break from a GMAKE foreach loop and then exit from


From: Pierre Rouleau
Subject: Re: Is it possible to break from a GMAKE foreach loop and then exit from make?
Date: Sun, 29 May 2022 11:50:19 -0400

On Sat, May 28, 2022 at 2:11 AM Kaz Kylheku <kaz@kylheku.com> wrote:

> On 2022-05-27 06:35, Pierre Rouleau wrote:
> > Hi all,
> >
> > I have a makefile tha patches the kernel but does not check if the patch
> > succeeded.
> > The rule is shown below.  It uses a foreach loop to apply a set of
> patches
> > identified by
> > a list of patches.
> >
> > Is it possible to use the `|| exit 1' construct inside the text portion
> of
> > the foreach loop to detect
> > failing patches and stop make execution?
>
> As you know, foreach is run by Make, like a macro. The generated shell code
> then performs exit detection.
>
> What you probably want is to generate clauses joined by &&
>
>   $(foreach ....) --> patch < this && patch < that && ... && patch < last
>
> You mean unroll the loop manually?
Unfortunately the file I'm dealing with is part of a *large* build system
with over 2000 make file, with make recursion and multi-layer decision
making
 that end up building the list of patch files, storing it inside a
variable.

Are you also saying that adding `|| exit 1' to the statement inside the
foreach loop would not work?
ie as in:
        (cd $(OUTPUT_ROOT_DIR)/$(CFG_GLOBAL_LINUX_VERSION); $(foreach
thepatch,$(KERNEL_PATCH_ONE),echo patching $(thepatch); patch
--ignore-whitespace -p1 < $(thepatch) || exit 1;))



> I believe that "set -e" also works, keeping in mind that each recipe
> line is run in a separate shell invocation (in the absence of .ONESHELL:
> being used).
>
> So that is to say:
>
>    target: prereq
>         set -e; command; command; command; ...
>
> with set -e, the shell will bail upon the first unsuccessful command,
> with a failed termination status, much like the way Make bails on the
> first unsuccessful recipe line.
>
> Compare the effect of removing "set -e" from this Makefile:
>
>   .PHONY: all
>
>   all:
>         set -e; echo foo; false; true
>
> Interesting: with set -e it stops on false, without it, it completes as if
everything was fine.
In the end do you mean that all I could do is prepend the rule with  `set
-e; ' and that would ensure termination on the first error?
As in:
         set -e; (cd $(OUTPUT_ROOT_DIR)/$(CFG_GLOBAL_LINUX_VERSION);
$(foreach thepatch,$(KERNEL_PATCH_ONE),echo patching $(thepatch); patch
--ignore-whitespace -p1 < $(thepatch)))



>
> >
> > ie, Is it possible to transform the following:
> >
> > $(OUTPUT_ROOT_DIR)/.kernel_patched: $(OUTPUT_ROOT_DIR)/.kernel_original
> >         @echo -e "Applying only specific patch to kernel"
> >         (cd $(OUTPUT_ROOT_DIR)/$(CFG_GLOBAL_LINUX_VERSION); $(foreach
> > thepatch,$(KERNEL_PATCH_ONE),echo patching $(thepatch); patch
> > --ignore-whitespace -p1 < $(thepatch);))
> >
> >
> > into this and is it the best way or are there better alternatives?
>
> The better alternative is to patch like it's 2002 and use the quilt
> program.
>
> I agree that it'd be nice to use quilt, unfortunately, the work
environment I have to deal with is somewhat constrained...
However, thanks for the advice, I might be able to use it in other
circumstances.

-- 
/Pierre


reply via email to

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