bugmake - Bugs: bug #40431, .SHELLFLAGS is passed to shell as...

 
 

bug #40431: .SHELLFLAGS is passed to shell as single argument.

Submitted by:  Van de Bugger <van_de_bugger>
Submitted on:  Wed 30 Oct 2013 09:15:32 PM UTC  
 
Severity: 3 - NormalItem Group: None
Status: DuplicatePrivacy: Public
Assigned to: NoneOpen/Closed: Closed
Component Version: 3.82Operating System: POSIX-Based
Fixed Release: NoneTriage Status: None

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

Sun 03 Nov 2013 08:40:05 PM UTC, comment #3:

First, having -e enabled by default for recipes is a requirement of the latest POSIX spec. GNU make by default adheres to the previous POSIX spec in this respect, where -e was required to NOT be present. I'm not willing to break backward-compatibility in this way, even if POSIX doesn't care. If you use the .POSIX: pseudo-target to request POSIX-compatibility mode, then -e will be enabled by default and you don't need to change .SHELLFLAGS.

Second, the behavior of .SHELLFLAGS with multiple options is correct in the currently released version of GNU make (4.0):

Third, make's standard shell is /bin/sh, not bash. The POSIX shell does not support flags such as -o pipefail and when bash is invoked as /bin/sh, it does not either:

So, if you want to use bash features in your makefiles then you must specifically request bash as the shell:

Paul D. Smith <psmith>
Project Administrator
Thu 31 Oct 2013 10:41:36 PM UTC, comment #2:

Thanks, I also found this trick independently. Unfortunately the trick does not work. Or, stricly speaking, it works, but there is an unwanted side effect which makes it useless. Look:

# Note: in current shell pipefail is not set.
$ echo $SHELLOPTS
braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
# Starting a new shell with "-o pipefail".
$ bash -o pipefail
# In nested shell pipefail is set.
$ echo $SHELLOPTS
braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:pipefail
# Starting one more nested shell:
$ bash
# In gransson, pipefail is not set.
$ echo $SHELLOPTS
braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor

It looks like shell options (real shell options specified in command line) are not inherited.

Now let us try to set SHELLOPTS variable:

# In current shell pipefailis not set:
$ echo $SHELLOPTS
braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
# Starting a nested shell with modified SHELLOPTS:
$ env SHELLOPTS=$SHELLOPTS:pipefail bash
# Here pipefail is set, as expected:
$ echo $SHELLOPTS
braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:pipefail
# Starting one more nested shell:
$ bash
# And check pipefail: it is still set!
$ echo $SHELLOPTS
braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor:pipefail

Effect of SHELLOPTS is inherited. Practically it means that many third-party shell scripts invoked from make directly or indirectly will not work, because they do not expect pipefail (or erexit).

In my real makefile there is a command:

rpmbuild -bb foo.spec

With

SHELLOPTS += pipefail:errexit

rpmbuild fails with no meanigful message. It reports something like this: "%install return non-zero status". I spend sometime to debug an issue and found that problem is in /usr/lib/rpm/check-buildroot script (it is an internal part of rpmbuild). It executes:

find ... | grep ... > $tmp

Grep finds nothing, returns status 1, and bash exits the script prematurely.

Thus, setting SHELLOPTS is not an option. :-(

Van de Bugger <van_de_bugger>
Thu 31 Oct 2013 04:30:45 AM UTC, comment #1:

This isn't the fix you were looking for, but for the record I think placing:

export SHELLOPTS = pipefail

in the makefile would solve your particular problem. The SHELLOPTS variable is read-only to bash so it cannot be set within the shell, thus the only way to get this behavior is with set -o pipefail, but you can modify and export SHELLOPTS from a non-bash parent process (such as make).

David Boyce <boyski>
Wed 30 Oct 2013 09:15:32 PM UTC, original submission:

I am trying to use .ONESHELL. I want shell to stop executing commands as soon as a command returns non-zero status. Here is my test Makefile:

.ONESHELL :
all :
false
echo "OK"

Ok, the test:

$ make
false
echo "OK"
OK

Oops, false returns non-zero status, but shell continues, it's bad. "set -e" as the first command of the recipe helps, but it is too boring and error-prone to add a command to every recipe. Let us try .SHELLFLAGS -- it seems it is what I need:

.SHELLFLAGS = -e -c

Oops:

$ make
false
echo "OK"
/bin/sh: - : invalid option
make: *** [all] Error 1

Error message is rather unclear. "-" is an invalid option? Ok, let us try another variant:

.SHELLFLAGS = -ec

$ make
false
echo "OK"
make: *** [all] Error 1

Ok, good. But it seems make treats value of .SHELLFLAGS as single argument. It may be suitable in simple cases, but it is not good in more complex scenarios.

Now let us try solve another task: Stop execution if any command in pipe fails. Here is modified Makefile:

.ONESHELL :
.SHELLFLAGS = -ec
all :
false | true
echo "OK"

By default, status of pipe is a status of the last command. Thus, "true" will hide a problem occurred before, and execution will continue:

$ make
false | true
echo "OK"
OK

I want the process stopped. It could be done by bash command

set -o pipefail

(All the commands in pipe will be completed, but execution will not go further.) Unfortunately, there is no short one-letter option to enable pipefail which can be bundled with -ec. The only way to enable pipefail is "-o pipefail", but

.SHELLFLAGS = -o pipefail -ec

does not work.

Resume: I think it would be helpful if make splits value of .SHELLFLAGS into words and pass every word to shell as a separate argument.

Van de Bugger <van_de_bugger>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by psmith (Posted a comment)
  • -unavailable- added by boyski (Posted a comment)
  • -unavailable- added by van_de_bugger (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 2 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Sun 03 Nov 2013 08:40:05 PM UTCpsmithStatusNone=>Duplicate
      Open/ClosedOpen=>Closed

    Back to the top


    Powered by Savane 3.1-cleanup1