A rule describes when and how certain files (rule's targets) are created. It can also serve to update a target file if any of the files required for its creation (target's prerequisites) are newer than the target.
Rules follow the syntax below: (Note that commands following a rule are indented by a tab)
targets: prerequisites
<commands>
where targets and prerequisites are file names or special reserved names and commands (if present) are executed by a shell to build/rebuild targets that are out-of-date.
To execute a rule one can simply run the make
command in the terminal from the same directory where the Makefile resides. Running make
without specifying the target, will execute the first rule defined in the Makefile. By convention, the first rule in the Makefile is often called all or default, commonly listing all valid build targets as prerequisites.
make
only executes the rule if the target is out-of-date, meaning either it doesn't exist or its modification time is older than any of its prerequisites. If the list of prerequisites is empty, the rule will only be executed when it is first invoked to build the targets. However, when the rule does not create a file and the target is a dummy variable, the rule will always be executed.
Pattern rules are used to specify multiple targets and construct prerequisite names from target names. They are more general and more powerful compared to ordinary rules as each target can have its own prerequisites. In pattern rules, a relationship between a target and a prerequisite is build based on prefixes including path names and suffixes, or both.
Imagine we want to build the targets foo.o
and bar.o
, by compiling C scripts, foo.c
and bar.c
, respectively. This could be done by using the ordinary rules below:
foo.o: foo.c
cc -c $< -o $@
bar.o: bar.c
cc -c $< -o $@
where automatic variable $<
is the name of the first prerequisite and $@
the name of the target (A complete list of automatic variables can be found here).
However, as the targets share the same suffix, the above two rules can now be substituted by the following pattern rule:
%.o: %.c
cc -c $< -o $@
Implicit rules tell make
how to use customary methods to build certain types of target files, which are used very often. make
uses the target file name to determine which implicit rule to invoke.
The pattern rule example we saw in the previous section, does not actually need to be declared in a Makefile as make
has an implicit rule for C compilation. Thus, in the following rule, the prerequisites foo.o
and bar.o
will be build using the implicit rule for C compilation, before building foo
.
foo : foo.o bar.o
cc -o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)
A catalogue of implicit rules and the variables used by them can be found here.