# Makefile Variables **Variables** in Make store strings (compiler names, flags, file lists). Use `VAR = value` to define, `$(VAR)` to expand. ```makefile CC = gcc CFLAGS = -O3 -Wall -g SRCS = main.c util.c helper.c OBJS = main.o util.o helper.o app: $(OBJS) $(CC) $(CFLAGS) -o app $(OBJS) ``` `$(CC)` expands to `gcc`, `$(CFLAGS)` to `-O3 -Wall -g`. Changing `CC` once updates every recipe that uses it. **Automatic variables** are special—Make sets them for each recipe: ```makefile $@ target filename $< first prerequisite $^ all prerequisites (space-separated) $+ all prerequisites (with duplicates) ``` Example: ```makefile main.o: main.c $(CC) $(CFLAGS) -c $< -o $@ ``` `$<` is `main.c`, `$@` is `main.o`. The recipe becomes: `gcc -O3 -Wall -g -c main.c -o main.o`. **Generic rule with automatic variables:** ```makefile %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ ``` This rule matches any `.o` depending on `.c`: `main.o` from `main.c`, `util.o` from `util.c`, etc. `$<` is the matching `.c` file, `$@` is the `.o` file. **Variable assignment modes:** ```makefile VAR = value # lazy (expands when used) VAR := value # immediate (expands when defined) VAR ?= value # conditional (only if not set) VAR += value # append ``` `=` is most common. `:=` is useful when you need the value immediately (e.g., in conditionals). **Built-in variables:** ```makefile CC C compiler (default: cc) CFLAGS C compiler flags LDFLAGS linker flags LDLIBS libraries to link ``` Make has defaults for these; override in your Makefile or on the command line: `make CFLAGS=-O2`. **Command-line variables:** ```bash make CFLAGS=-O2 # override in this run make CC=clang # use a different compiler ``` These take precedence over Makefile definitions. **String functions:** Variables can use functions like `patsubst` (pattern substitution): ```makefile SRCS = main.c util.c OBJS = $(patsubst %.c, %.o, $(SRCS)) # main.o util.o ``` `patsubst` replaces patterns. More on functions in [[makefile-functions]].