BudiBadu Logo
Samplebadu

Makefile by Example: Macros

GNU Make 4.x

Macros (variables) can be assigned in different ways. This example clarifies `=`, `:=`, `?=`, and `+=`.

Code

# = : Recursive assignment
# Value is evaluated when used, not when defined
FOO = $(BAR)
BAR = later

# := : Simple assignment (Immediate)
# Value is evaluated immediately
X := foo
Y := $(X) bar
X := later

# ?= : Conditional assignment
# Only assign if not already defined (e.g. from environment)
CC ?= gcc

# += : Append
CFLAGS := -Wall
CFLAGS += -O2

all:
	@echo "FOO is $(FOO)"    # Prints "later"
	@echo "Y is $(Y)"        # Prints "foo bar"
	@echo "CC is $(CC)"
	@echo "CFLAGS is $(CFLAGS)"

Explanation

Make offers several flavors of variable assignment, which can be confusing. The standard = operator defines a recursively expanded variable. The value is calculated only when the variable is used, not when it's defined. This allows you to reference variables defined later in the file, but can be slower.

The := operator defines a simply expanded variable. The value is calculated immediately at the point of definition. This behaves like variables in most other programming languages and is generally preferred for predictability and performance.

The ?= operator assigns a value only if the variable is not yet defined. This is perfect for allowing users to override settings via environment variables (e.g., CC=clang make). The += operator appends text to an existing variable, adding a space automatically.

Code Breakdown

3
FOO = $(BAR) uses recursive expansion. Since BAR is "later" when FOO is printed, FOO becomes "later".
13
CC ?= gcc lets you run make to use gcc, or CC=clang make to use clang.