Variables
Scope: naming values instead of repeating them — the three assignment flavors and command-line overrides.
Why variables
The C build repeats gcc -Wall -Wextra -g in every
recipe. Name it once:
CC = gcc
CFLAGS = -Wall -Wextra -g
hello: main.o greet.o
$(CC) $(CFLAGS) -o hello main.o greet.o
Reference with $(NAME) (or ${NAME}). Change the
flags in one place, and every recipe follows.
The three flavors
A = one
B = $(A) two
A = three
C := $(A) four
$ make show
B=three two
C=three four
=(recursive): the value is re-expanded every time it's used.Bpicks up the later value ofA—three, notone. This is the default and the source of most "why did that change?" surprises.:=(simple): expanded once, when the line is read.CfrozeAasthree.?=(conditional): assign only if the variable is not already set. The standard way to write a default the user may override:
BUILD_DIR ?= build
Command-line override
Any variable can be overridden when you run Make:
$ make show A=ZERO
B=ZERO two
C=ZERO four
Command-line definitions beat Makefile assignments —
even := lines expand with the command-line value, as
the real output above shows. (One exception: override
directives in the Makefile, which are rare enough to
look up when you meet them.)
This is the everyday customization mechanism: make
BUILD_DIR=/tmp/build, make CFLAGS="-O2". Design your
Makefiles so the things people change are variables.
Environment variables
Make imports the shell's environment as variables — but a Makefile assignment wins over the environment, while the command line beats both. Precedence, highest first:
- Command line:
make VAR=value - Makefile assignment
- Environment:
export VAR=value - Make's built-in defaults (like
CC = cc)
So CFLAGS in your environment is a suggestion; CFLAGS
in the Makefile is a decision.
Check: make -p | grep -A2 '^CFLAGS' shows where a
variable got its value (among several pages of output —
make -p prints the entire database).