Automatic Variables
Automatic variables in GNU Make are special built-in variables whose values are computed dynamically for each rule based on its target and prerequisites. They allow you to write generic, reusable recipes rather than hardcoding file names.
Critical Scope Rule: Automatic variables are only accessible within the recipe (the command block) of a rule. You cannot use them in the target list or the prerequisites list of a standard rule, as they will evaluate to an empty string there.
| Variable | Meaning | Use Case |
|---|---|---|
| $@ | Target name | |
| $% | Member name (for archive targets like lib.a(member.o)) | |
| $< | First prerequisite (dependency) | |
| $? | Prerequisites newer than the target | |
| $^ | All prerequisites (duplicates removed) | |
| $+ | All prerequisites (duplicates preserved) | |
| $* | Stem matched by % | |
| $| | Order-Only Prerequisites |
1. $@ — Target Name
app: main.o utils.o
gcc $^ -o $@
Expands to:
gcc main.o utils.o -o app
Where: $@ = app
2. $< — First Prerequisite
%.o: %.c
gcc -c $< -o $@
When building main.o:
$< = main.c
$@ = main.o
Expands to:
gcc -c main.c -o main.o
3. $^ — All Prerequisites (Unique)
app: main.o utils.o
gcc $^ -o $@
Expands to:
gcc main.o utils.o -o app
$^ = main.o utils.o
Duplicates are removed.
Example:
app: main.o utils.o main.o
$^ = main.o utils.o
4. $+ — All Prerequisites (Keep Duplicates)
app: main.o utils.o main.o
echo $+
Output:
main.o utils.o main.o
Useful when link order matters.
5. $? — Newer Prerequisites
Suppose:
app: main.o utils.o
If only main.o changed since the last build:
$? = main.o
Useful for incremental updates.
Example:
lib.a: main.o utils.o
ar rcs $@ $?
Only updated object files are added to the archive.
6. $* — Stem
Pattern rule:
%.o: %.c
echo $*
For:
main.o <- main.c
Output:
main
$* = main
For:
driver.o <- driver.c
$* = driver
7. $% — Archive Member
Used with static libraries.
lib.a(main.o): main.o
ar r lib.a main.o
$@ = lib.a
$% = main.o
Rarely used outside archive-related Makefiles.
8. $| — Order-Only Prerequisites
Example:
app: main.o | builddir
$| = builddir
Order-only prerequisites affect build order but do not trigger rebuilds if they change.
Common usage:
obj/%.o: src/%.c | obj
gcc -c $< -o $@
Ensure the obj directory exists before compiling.
©2023-2024 rculock.com