error checking version of $(shell)

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

error checking version of $(shell)

Britton Kerin
On Mon, May 18, 2020 at 11:24 AM Pete Dietl <[hidden email]> wrote:
>
> Speaking of
>
> > return value of a call to $(shell) is available in $(.SHELLSTATUS).
>
> I think it would be a nice addition to have some global setting where
> any failed $(shell )
> command automatically fails Make.

Agreed.  I have a couple different approaches for this lying around:

# This function works almost exactly like the builtin shell command, except it
# stops everything with an error if the shell command given as its argument
# returns non-zero when executed.  The other difference is that the output
# is passed through the strip make function (the shell function strips
# only the last trailing newline).  In practice this doesn't matter much
# since the output is usually collapsed by the surroundeing make context
# to the same result produced by strip.  WARNING: don't try to nest calls
# to this function.
SHELL_CHECKED = \
  $(strip \
    $(if $(shell (($1) 1>/tmp/SC_so) || echo 'non-empty'), \
      $(error shell command '$1' failed.  Its stderr should be above \
              somewhere.  Its stdout is available for review in '/tmp/SC_so'), \
      $(shell cat /tmp/SC_so)))

# FIXME: SHELL_CHECKED should probably be replaced with this better version,
# which should work ok with both parallel make and nested calls.  I'm hoping
# for a little more feedback from paul declaring that the parser is indeed
# sequential and .SHELLSTATUS is indeed per-process, so that this is ok.
# This currently loses the /tmp/SC_so so it migth be harder to get a look
# at the output of a failing command.  That could be restored by making a
# random-named temp file, and putting the command and it's output in there,
# if that ever seems worth it.
SHELL_CK = \
  $(shell $1) $(if $(filter $(.SHELLSTATUS),0),,$(error command '$1' failed))

Britton

Reply | Threaded
Open this post in threaded view
|

Re: error checking version of $(shell)

Paul Smith-20
On Mon, 2020-05-18 at 19:16 -0800, Britton Kerin wrote:
> # I'm hoping
> # for a little more feedback from paul declaring that the parser is indeed
> # sequential and .SHELLSTATUS is indeed per-process, so that this is ok.

GNU make is not multithreaded and all invocations of $(shell ...)
functions happen serially and are completed before the next step is
taken, and .SHELLSTATUS is a normal make variable (that is, it's
globally set when the shell function runs).

Your second option should work fine.