Is there a way to exit with an error condition if a file does not exist? I am currently doing something like this:
all: foo foo: test -s /opt/local/bin/gsort || echo "GNU sort does not exist! Exiting..." && exit
Running make
runs the all
target, which runs foo
.
The expectation is that if the test -s
conditional fails, then the echo/exit
statements are executed.
However, even if /usr/bin/gsort
exists, I get the result of the echo
statement but the exit
command does not run. This is the opposite of what I am hoping to accomplish.
What is the correct way to do something like the above?
myApp is for myApplication i.e. the filename by the build process. If you just want to avoid make stopping if the file does not exist, rm -rf myApp could be an alternative. Or preceding the command with a dash ( -rm myApp ) to make make ignore the error from rm (it will however print an ugly message).
The ifeq directive begins the conditional, and specifies the condition. It contains two arguments, separated by a comma and surrounded by parentheses. Variable substitution is performed on both arguments and then they are compared.
When you type make or make [target] , the Make will look through your current directory for a Makefile. This file must be called makefile or Makefile . Make will then look for the corresponding target in the makefile. If you don't provide a target, Make will just run the first target it finds.
By default, the goal is the first target in the makefile (not counting targets that start with a period). Therefore, makefiles are usually written so that the first target is for compiling the entire program or programs they describe.
I realize this is a bit old at this point, but you don't need to even use a subshell to test if a file exists in Make.
It also depends on how you want/expect it to run.
Using the wildcard function, like so:
all: foo foo: ifeq (,$(wildcard /opt/local/bin/gsort)) $(error GNU Sort does not exist!) endif
is one good way to do it. Note here that the ifeq clause is not indented because it is evaluated before the target itself.
If you want this to happen unconditionally for every target, you can just move it outside of a target:
ifeq (,$(wildcard /opt/local/bin/gsort)) $(error GNU Sort does not exist!) endif
exit
alone returns the status of the last command executed. In this case, it returns zero, which means everything is ok.
This is, because ||
and &&
have equal precedence, and the shell interprets the command as if it were written
( test ... || echo ... ) && exit
If you want to signal failure you must exit with a non zero value, e.g. exit 1
. And if you want to echo and exit, just put the commands in sequence separated by ;
all: foo foo: test -s /opt/local/bin/gsort || { echo "GNU sort does not exist! Exiting..."; exit 1; }
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