How to make a failing $(shell) command interrupt Make
You should use a regular target to create BuildRules.mk:
BuildRules.mk: collect_sources.py
python $< >$@
include BuildRules.mk
This is the standard trick to use when automatically generating dependencies.
Ok, here's my own solution, which is unfortunately not based on the status code of the collect_sources.py script, but which Works For Me (TM) and lets me see any output that the script produces:
SHELL_OUTPUT := $(shell python collect_sources.py 2>&1)
ifeq ($(filter error: [Errno %],$(SHELL_OUTPUT)),)
$(info $(SHELL_OUTPUT))
else
$(error $(SHELL_OUTPUT))
endif
The script is written so that any error produces an output beginning with "collect_sources: error:"
. Additionally, if python cannot find or execute the given script, it outputs an error message containing the message "[Errno 2]"
or similar. So this little piece of code just captures the output (redirecting stderr to stdout) and searches for error messages. If none is found, it simply uses $(info)
to print the output, otherwise it uses $(error)
, which effectively makes Make stop.
Note that the indentation in the ifeq ... endif
is done with spaces. If tabs are used, Make thinks you're trying to invoke a command and complains about it.
There might be a better way, but I tried the following and it works:
$(if $(shell if your_command; then echo ok; fi), , $(error your_command failed))
Here I did assume that your_command
does not give any output, but it shouldn't be hard to work around such a situation.
Edit: To make it work with the default Windows shell (and probably any decent shell) you could write your_command && echo ok
instead of the if
within the shell
function. I do not think this is possible for (older) DOS shells. For these you probably want to adapt your_command
or write a wrapper script to print something on error (or success).