Make Built-in Functions Reference
Learn essential Make functions: wildcard, patsubst, filter, foreach, call, shell, and text manipulation functions with practical build system examples.
Detailed Explanation
Essential Make Functions
Make provides built-in functions for string manipulation, file operations, and flow control. These functions are invoked with $(function arguments) syntax.
File Functions
# Find all .c files recursively
SRCS := $(shell find src -name '*.c')
# Find .c files in one directory (no shell)
SRCS := $(wildcard src/*.c)
# Convert .c files to .o files
OBJS := $(patsubst src/%.c,build/%.o,$(SRCS))
# Alternative substitution syntax
OBJS := $(SRCS:.c=.o)
wildcard expands glob patterns. patsubst performs pattern substitution with % as the wildcard. The :.c=.o shorthand is equivalent to patsubst %.c,%.o.
String Functions
SRCS = main.c utils.c test_main.c test_utils.c
# Filter: keep only matching words
TEST_SRCS = $(filter test_%,$(SRCS))
# Result: test_main.c test_utils.c
# Filter-out: remove matching words
PROD_SRCS = $(filter-out test_%,$(SRCS))
# Result: main.c utils.c
# Sort and deduplicate
UNIQUE = $(sort z a m a z)
# Result: a m z
# Word functions
FIRST = $(firstword $(SRCS))
# Result: main.c
COUNT = $(words $(SRCS))
# Result: 4
Foreach and Call
DIRS = src lib tests
# Create all directories
$(foreach d,$(DIRS),$(shell mkdir -p $(d)))
# Generate rules with define/call
define COMPILE_RULE
$(2)/%.o: $(1)/%.c
@mkdir -p $$(@D)
$$(CC) $$(CFLAGS) -c -o $$@ $$<
endef
$(eval $(call COMPILE_RULE,src,build))
Conditional Functions
# $(if condition,then,else)
CC := $(if $(shell which clang 2>/dev/null),clang,gcc)
# $(or ...) — first non-empty value
PYTHON := $(or $(shell which python3),$(shell which python),python)
# $(and ...) — empty if any arg is empty
HAS_TOOLS := $(and $(shell which gcc),$(shell which make))
The shell Function
GIT_HASH := $(shell git rev-parse --short HEAD)
NUM_CPUS := $(shell nproc 2>/dev/null || sysctl -n hw.ncpu)
$(shell ...) executes a command and captures its stdout. Use := (immediate assignment) to run the command once at parse time, not on every reference.
Key Tips
- Use
$(wildcard)instead of$(shell find ...)when possible — it is faster $(sort)both sorts and removes duplicates$(strip)removes leading/trailing whitespace — useful after variable expansion- Always use
:=with$(shell)to avoid re-executing commands
Use Case
Writing advanced Makefile rules that need to manipulate file lists, filter sources, generate targets dynamically, and use conditional logic based on available system tools.