Rules: targets, prerequisites, recipes

Make · Essentials · 10 min

Every Makefile, from a two-line task runner to a large C build, is made of this one construct.

A rule has three parts:

target: prerequisites
	recipe line
	recipe line
  • The target is usually a file the rule produces, such as app or main.o.
  • The prerequisites are files (or other targets) it is built from.
  • The recipe is one or more shell commands. Each recipe line must start with a tab character, not spaces. That is the most famous make error: *** missing separator. Stop.

Run make target to build a target, or plain make to build the default goal, which is the first target in the file (by convention named all).

To build a target, make first makes sure each prerequisite is up to date, recursively applying their rules, then runs the target's recipe if needed. So rules form a dependency graph, and make walks it from the bottom up.

Before running each recipe line make prints it (the echo can be silenced, as shown later). If a command fails (non-zero exit status), make stops immediately with an error, so later steps never run on broken inputs.

A Makefile is normally called Makefile in the project root; make -f other.mk uses another file.

Example

app: main.o util.o
	cc -o app main.o util.o

main.o: main.c util.h
	cc -c main.c

util.o: util.c util.h
	cc -c util.c

# $ make
# cc -c main.c
# cc -c util.c
# cc -o app main.o util.o
# $ make
# make: 'app' is up to date.

Remember

  • target: prerequisites, then tab-indented recipe lines
  • Plain make builds the first target in the file
  • make stops at the first failing command

Watch out for

  • Indenting recipes with spaces (often an editor setting), which gives 'missing separator'.

Check yourself

  1. What does make build when run with no arguments?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.gnu.org/software/make/manual/make.html#Rule-Introduction