Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

makefile pattern rules without recipes

Tags:

makefile

rules

I'm observing an interesting behavior of make and I wonder if there is a reasonable explanation to it besides a bug in gmake.

Let's say we have the following in makefile:

%-animal:
        echo "$* is an animal"

%-fox: %-fox-animal

%-wolf: %-wolf-animal

The difference between the last two targets is that "%-wolf" does not have any recipe, and "%-fox" has an empty recipe (i.e. just a line with a tab at the beginning).

When we try to execute the rules, here's what happens:

[root@cv19 tmp]# make freddy-animal
echo "freddy is an animal"
freddy is an animal
[root@cv19 tmp]# make freddy-wolf
make: *** No rule to make target `freddy-wolf'.  Stop.
[root@cv19 tmp]# make freddy-fox
echo "freddy-fox is an animal"
freddy-fox is an animal

i.e.the pattern rule that has a recipe (although an empty one) works, the one that doesn't does not. Am I missing something in the way it's supposed to work?

like image 489
m1tk4 Avatar asked Sep 16 '10 16:09

m1tk4


People also ask

What is pattern rule in makefile?

A pattern rule looks like an ordinary rule, except that its target contains the character ' % ' (exactly one of them). The target is considered a pattern for matching file names; the ' % ' can match any nonempty substring, while other characters match only themselves.

Can you have multiple rules in a makefile?

There can only be one recipe to be executed for a file. If more than one rule gives a recipe for the same file, make uses the last one given and prints an error message. (As a special case, if the file's name begins with a dot, no error message is printed.

What is the default rule in a makefile?

The default goal is the target of the first rule in the first makefile. If the first rule has multiple targets, only the first target is taken as the default.


1 Answers

Pattern rules with no recipes at all are documented as meaning something quite different from those providing a recipe, even an empty one. Instead they cancel any pre-existing implicit rule:

You can cancel a built-in implicit rule by defining a pattern rule with the same target and prerequisites, but no recipe.

Thus your "%-wolf" pattern actually serves to cancel any existing implicit rule for %-wolf-animal -> %-wolf. And there wasn't one anyway.

like image 189
John Marshall Avatar answered Sep 21 '22 08:09

John Marshall