How could I abort a make/makefile execution based on a makefile's variable not being set/valued?
I came up with this, but works only if caller doesn't explicitly run a target (i.e. runs make
only).
ifeq ($(MY_FLAG),)
abort: ## This MUST be the first target :( ugly
@echo Variable MY_FLAG not set && false
endif
all:
@echo MY_FLAG=$(MY_FLAG)
I think something like this would be a good idea, but didn't find anything in make's manual:
ifndef MY_FLAG
.ABORT
endif
You can use an IF to test:
Result:
TL;DR: Use the
error
function:Note that the lines must not be indented. More precisely, no tabs must precede these lines.
Generic solution
In case you're going to test many variables, it's worth defining an auxiliary function for that:
And here is how to use it:
This would output an error like this:
Target-specific check
It is also possible to extend the solution so that one can require a variable only if a certain target is invoked.
$(call check_defined, ...)
from inside the recipeJust move the check into the recipe:
The leading
@
sign turns off command echoing and:
is the actual command, a shell no-op stub.Showing target name
The
check_defined
function can be improved to also output the target name (provided through the$@
variable):So that, now a failed check produces a nicely formatted output:
check-defined-MY_FLAG
special targetPersonally I would use the simple and straightforward solution above. However, for example, this answer suggests using a special target to perform the actual check. One could try to generalize that and define the target as an implicit pattern rule:
Usage:
Notice that the
check-defined-BAR
is listed as the order-only (|...
) prerequisite.Pros:
Cons:
make -t
(see Instead of Executing Recipes) will pollute your root directory with lots ofcheck-defined-...
files. This is a sad drawback of the fact that pattern rules can't be declared.PHONY
.I believe, these limitations can be overcome using some
eval
magic and secondary expansion hacks, although I'm not sure it's worth it.Use the shell function
test
:Usage:
Use the shell error handling for unset variables (note the double
$
):If you need a custom error message, add it after the
?
: