I want to run certain action in the shell depending on whether a default makefile in the current directory contains a certain target.
#!/bin/sh
make -q some_target
if test $? -le 1 ; then
true # do something
else
false # do something else
fi
This works, because GNU make returns error code 2 if the target is absent, 0 or 1 otherwise. The problem is that is not documented this way. Here is a slice of the man:
-q, --question
``Question mode''. Do not run any commands, or print anything;
just return an exit status that is zero if the specified targets
are already up to date, nonzero otherwise.
Only zero/nonzero is distinguished. What is the right way to do that?
You should read the GNU make manual rather than the man page: the man page is merely a summary not a complete definition. The manual says:
The exit status of make is always one of three values:
0 The exit status is zero if make is successful
2 The exit status is two if make encounters any errors. It will print messages
describing the particular errors.
1 The exit status is one if you use the ‘-q’ flag and make determines that
some target is not already up to date.
Since trying to create a target that doesn't exists is an error, you'll always get an exit code of 2 in that situation.
Late answer, but perhaps it will help people facing the same problem in the future.
I use the approach below, which does require you to modify the Makefile (you need to add a single %-rule-exists pattern rule). If you don't want to do that, you can just run make -n your-target-to-check &> /dev/null
directly from your script.
I use this to have commands like autobuild and autoupload, which are included for context in the snippet.
%-rule-exists:
@$(MAKE) -n $* &> /dev/null
auto%: %-rule-exists
$(info Press CTRL-C to stop $*ing)
@while inotifywait -qq -r -e move -e create -e modify -e delete --exclude "\.#.*" src; do make $* ||: ; date ; done
Example output:
$ make build-rule-exists; echo Exit code: $?
Exit code: 0
$ make nonsense-rule-exists; echo Exit code: $?
Exit code: 2
Note that it does not actually build the target to find out if the rule exists, courtesy of the -n
flag of make
. I needed it to work even if a build would fail.
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