4.1 Targets and dependencies
The make program attempts to bring a target up to date by
bring all of the target's dependencies up to date. These dependencies
may have further dependencies. Thus, a potentially complex dependency
graph forms when processing a typical `Makefile'. From a simple
`Makefile' that looks like this:
|
all: foo
foo: foo.o bar.o baz.o
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
.l.c:
$(LEX) $< && mv lex.yy.c $@
|
We can draw a dependency graph that looks like this:
|
all
|
foo
|
.-------+-------.
/ | \
foo.o bar.o baz.o
| | |
foo.c bar.c baz.c
|
baz.l
|
Unless the `Makefile' contains a directive to make , all
targets are assumed to be filenames, and rules must be written to create
these files or somehow bring them up to date.
When leaf nodes are found in the dependency graph, the `Makefile'
must include a set of shell commands to bring the dependent up to date
with the dependency. Much to the chagrin of many make users,
up to date means the dependent has a more recent timestamp than
the target. Moreover, each of these shell commands are run in their own
sub-shell and, unless the `Makefile' instructs make
otherwise, each command must exit with an exit code of 0 to indicate
success.
Target rules can be written which are executed unconditionally. This is
achieved by specifying that the target has no dependents. A simple rule
which should be familiar to most users is:
|