help-make
[Top][All Lists]
Advanced

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

Re: Can the exit status of the code block in @(...) be obtained from out


From: Paul Smith
Subject: Re: Can the exit status of the code block in @(...) be obtained from outside the @() structure?
Date: Tue, 18 Jan 2022 13:55:55 -0500
User-agent: Evolution 3.36.5-0ubuntu1

On Tue, 2022-01-18 at 10:14 +0800, Hongyi Zhao wrote:
> But it seems that the `$?' used above can't obtain the exit status of
> the code block in @(...) when used from outside the @() structure
> [2].  So, I want to know if I can reliably obtain the exit status of
> the code block in @(...) from outside the @() structure. Any hints
> will be greatly appreciated.

First, of course you must use $$? not $?, because $? is a shell
variable not a make variable so you must escape it from make.

Second, there's nothing magical about ().

All versions of make, including GNU make, invoke each logical line of
the recipe in a separate shell.  There is no interaction between two
different shells: the exit code of one shell cannot be accessed by a
sibling shell.

A rule like this:

    foo:
            (exit 1)
            echo $$?

causes make to invoke two different shells:

  /bin/sh -c '(exit 1)'
  /bin/sh -c 'echo $?'

The exit code of the first shell is not put into the $? variable of the
second shell.

If you want to access the exit code of a previous command you must put
them both into the same shell, which means they both need to be in the
same logical line of the recipe.  So, this rule:

    foo:
            (exit 1) ; \
            echo $$?

invokes a single shell command:

  /bin/sh -c '(exit 1) ; echo $?'

now it will work as you expect.

So, in your makefile rule, you just need to make sure that you add
semicolons and backslashes to ensure that the recipe is treated as one
logical line; change:

  echo "*** located here $(2)" ; \
  exit 1 ; fi ; fi ; fi)
  if test $? -eq 0 -a ! -e ../$(3); then \

to add the semicolon / backslash:

  echo "*** located here $(2)" ; \
  exit 1 ; fi ; fi ; fi) ; \
  if test $$? -eq 0 -a ! -e ../$(3); then \




reply via email to

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