GNU make automatic variables
When make runs a recipe it sets a handful of one-character automatic
variables that name the target, the prerequisites and the pattern stem.
Knowing them lets you write generic pattern rules instead of repeating file
names. This reference lists every automatic variable, its meaning, and the
D/F directory and file suffixes you can attach to each.
How it works
Automatic variables are set fresh for each rule that fires and are only valid inside that rule’s recipe (not in prerequisite lists, except via secondary expansion). The core ones:
%.o: %.c
$(CC) -c $< -o $@ # $< = first prereq (foo.c), $@ = target (foo.o)
program: main.o util.o
$(CC) $^ -o $@ # $^ = all prereqs deduped, $@ = program
For any automatic variable X, the forms $(XD) and $(XF) give the
directory part and the file part. So with target build/foo.o, $(@D) is
build and $(@F) is foo.o.
Tips and notes
$<is the first prerequisite — ideal as the single input to a compiler.$^deduplicates; reach for$+only when repeats matter (link order).$?is the subset of prerequisites that are newer than the target — handy for incremental archive updates.$*(the stem) is the safe way to derive sibling file names in pattern rules.- These are case-sensitive single characters;
$(MAKE),$(CURDIR)and friends are separate named special variables.
Common patterns in real Makefiles
Compile all C files to object files
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
$< provides exactly the matching .c file and $@ the target .o, so this one rule compiles every C source in the project without listing each file explicitly.
Build and rename using the stem
bin/%: src/%.c
$(CC) -o $@ $<
$* would hold the stem (e.g., main when building bin/main), useful if you need to derive other paths from it.
Archive update with $?
libfoo.a: foo.o bar.o baz.o
ar rcs $@ $?
$? is the subset of prerequisites newer than the target. For archive libraries this avoids re-archiving unchanged objects.
Extracting directory and file parts
$(OUTDIR)/%.o: %.c
mkdir -p $(@D)
$(CC) -c $< -o $@
$(@D) gives the directory part of the target, making it safe to create it before writing the output.
The D and F suffix table
| Variable | Meaning | Example target build/foo.o |
|---|---|---|
$@ | Full target name | build/foo.o |
$(@D) | Directory part | build |
$(@F) | File part | foo.o |
$< | First prerequisite | src/foo.c |
$(<D) | Directory of first prereq | src |
$(<F) | File of first prereq | foo.c |
$* | Pattern stem | foo |
The D/F suffixes work identically on $<, $^, $+, $?, and $*. They are especially useful for organizing outputs into separate build directories.