I have a Makefile that looks as follows:
.ONESHELL:
SHELL = /bin/bash
.SHELLFLAGS = -e
clean:
rm -f foo
.PHONY: clean
foo doesn't exist. When I run this on Debian, GNU Make 4.1 I get this error:
rm -f foo
/bin/bash: rm -f foo: No such file or directory
Makefile:6: recipe for target 'clean' failed
make: *** [clean] Error 1
When I run it on macOS, GNU Make 3.81 it works as expected. It makes no difference if I write -rm -f instead of rm -f.
Why do I get the error? Running bash -e -c "rm -f foo" ; echo $? in a shell prints 0 on both systems.
Am I missing something?
The error message has to be read quite carefully:
/bin/bash: rm -f foo: No such file or directory
This isn't a message from rm saying it can't find foo, it's a message from Bash telling it can't find the file rm -f foo (with the spaces in the filename).
With .SHELLFLAGS = -e, the shell gets what would equal the command line:
bash -e "rm -f foo"
So it looks for a file rm -f foo to read commands from. You need to explicitly add the -c flag to tell it to take the argument itself as a command, i.e. .SHELLFLAGS = -ec, resulting in
bash -ec "rm -f foo"
Not surprisingly, the default value for .SHELLFLAGS contains -c:
The argument(s) passed to the shell are taken from the variable
.SHELLFLAGS. The default value of.SHELLFLAGSis-cnormally, or-ecin POSIX-conforming mode.
That is an invalid setting for .SHELLFLAGS. It will result in this being invoked:
/bin/sh -e 'rm -f foo'
which is not a valid command line; it's telling the shell to run a program named, literally, rm -f foo which is obviously wrong. You have to be sure you add the -c option as well, and since many shells only allow options in the first argument, you'll need:
.SHELLFLAGS = -ec
This is documented in the GNU make manual.
The reason it "works" in the older GNU make 3.81 is that this version doesn't support the .SHELLFLAGS option at all, so that line is just ignored.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With