Pattern Rules

Overview

Teaching: 10 min
Exercises: 0 min

Questions

How can I define rules to operate on similar files?

Objectives

Write Make pattern rules.

Our Makefile still has repeated content. The rules for each .dat
file are identical apart from the text and data file names. We can
replace these rules with a single pattern
rule which can be used to build any
.dat file from a .txt file in books/:

%.dat :books/%.txt countwords.py
python countwords.py $<$*.dat

% is a Make wildcard. $* is a special
variable which gets replaced by the stem with
which the rule matched.

This rule can be interpreted as:
“In order to build a file named [something].dat (the target)
find a file named books/[that same something].txt (the dependency)
and run countwords.py [the dependency] [the target].”

Note that we can still use Make to build individual .dat targets as before,
and that our new rule will work no matter what stem is being matched.

$ make sierra.dat

which gives the output below:

python countwords.py books/sierra.txt sierra.dat

Using Make Wildcards

The Make % wildcard can only be used in a target and in its
dependencies. It cannot be used in actions. In actions, you may
however use $*, which will be replaced by the stem with which
the rule matched.

Where We Are

This episode has introduced pattern rules, and used the $* variable
in the dat rule in order to explain how to use it.
Arguably, a neater solution would have been to use $@ to refer to
the target of the current rule (see below),
but then we wouldn’t have learned about $*.

%.dat :books/%.txt countwords.py
python countwords.py $<$@

Key Points

Use the wildcard % as a placeholder in targets and dependencies.

Use the special variable $* to refer to matching sets of files in actions.