In the following makefile, the top level target top.stamp has dependency on missing.stamp but there is not recipe for missing.stamp. Why make doesn't flag this as an error? It just goes and builds all targets. I need this to be flagged as an error.
.SUFFIXES:
MAKEFLAGS += --no-builtin-rules
top.stamp: top_dep1.stamp top_dep2.stamp
@echo touching $@
@touch $@
top_dep1.stamp:
@echo touching $@
@touch $@
top_dep2.stamp: missing.stamp
@echo touching $@
@touch $@
missing.stamp: a.stamp b.stamp
a.stamp: top_dep1.stamp
@echo touching $@
@touch $@
b.stamp: top_dep1.stamp
@echo touching $@
@touch $@
.PHONY:clean
clean:
@rm -f *.stamp
Done google searches, GPT's are just going in circles with incorrect answers.
In the following makefile, the top level target top.stamp has dependency on missing.stamp but there is not recipe for missing.stamp. Why make doesn't flag this as an error? It just goes and builds all targets. I need this to be flagged as an error.
.SUFFIXES:
MAKEFLAGS += --no-builtin-rules
top.stamp: top_dep1.stamp top_dep2.stamp
@echo touching $@
@touch $@
top_dep1.stamp:
@echo touching $@
@touch $@
top_dep2.stamp: missing.stamp
@echo touching $@
@touch $@
missing.stamp: a.stamp b.stamp
a.stamp: top_dep1.stamp
@echo touching $@
@touch $@
b.stamp: top_dep1.stamp
@echo touching $@
@touch $@
.PHONY:clean
clean:
@rm -f *.stamp
Done google searches, GPT's are just going in circles with incorrect answers.
To my surprise, I don't find a dupe for this question. Maybe I'm having a bad search day, but supposing not, it warrants an answer.
why make doesn't complain about missing recipe?
Because there's nothing about that situation to complain about. The significance to make
is defined, and such constructs appear in many real-world makefiles. In partiular, many makefiles have a prerequisite-only rule for all
as their first rule, with no recipe for all
there or in any other rule. This is by no means the only such usage.
The thing to understand is that this should not be considered a special case. A target is out of date if there is no corresponding file, if the corresponding file is out of date relative to the target's prerequisites, if any of the prerequisites are out of date, or possibly for other reasons.* If such a target, T, is in the prerequisite tree for a goal target during a make
run, then its prerequisites necessarily are too. In that case, T's prerequisites will be ensured up to date. Some time later, make
executes the commands, if any, specified for bringing T itself up to date. No big deal if there are no such commands.
That seems not to be explicitly described by POSIX, nor either by the GNU make
manual, which is pretty thorough in most regards, but it is implicit in both. They talk about special targets that are not expected to have recipes, they provide examples of makefiles containing no-recipe rules (and no others) for certain targets, and POSIX, at least, talks about "a target with commands that is not up-to-date" (emphasis added), which implies that there may also be targets without commands. And GNU does talk about force targets, which illustrates a particular case of the more general behavior.
I need this to be flagged as an error.
That's unfortunate, because as far as make
is concerned, it is not erroneous. Nor do POSIX or GNU make
define any options for flagging such targets. If you are using GNU make
, however, then you could try parsing the output of env -i make -pnr
to identify targets without recipes. The main functional part of that is make -p
, which will dump make
's database after parsing the makefile(s). The other options and running it via env
serve to significantly trim down the output and to do the job without actually building anything. That would be more convenient for you than parsing your makefile(s) directly because make
will present only one rule for each target, and will annotate each with relevant information.
* For example, with GNU make
, a target that is a prerequisite of the .PHONY
special target will always be considered initially out of date, all other considerations notwithstanding.