# Makefile Functions **Make functions** manipulate strings and lists. Common ones: `wildcard`, `patsubst`, `subst`, `filter`, `foreach`. **`wildcard`** expands a glob pattern to a list of files: ```makefile SRCS = $(wildcard *.c) # main.c util.c helper.c OBJS = $(patsubst %.c, %.o, $(SRCS)) # main.o util.o helper.o ``` `$(wildcard *.c)` lists all `.c` files in the current directory. Essential for avoiding hardcoded file lists. **`patsubst`** replaces a pattern in a list: ```makefile SRCS = main.c util.c OBJS = $(patsubst %.c, %.o, $(SRCS)) # replaces .c with .o ``` Syntax: `$(patsubst pattern, replacement, list)`. Replace `%.c` with `%.o` in the list. **`subst`** replaces a substring: ```makefile SRCS = main.c util.c OBJS = $(subst .c, .o, $(SRCS)) # simple replacement ``` Unlike `patsubst`, `subst` doesn't use patterns—it replaces the exact string. **`filter`** selects items matching a pattern: ```makefile SOURCES = main.c util.c test.h helper.c C_FILES = $(filter %.c, $(SOURCES)) # main.c util.c helper.c ``` `$(filter %.c, ...)` keeps only `.c` files. **`filter-out`** removes items matching a pattern: ```makefile ALL_OBJS = main.o util.o test.o REAL_OBJS = $(filter-out test.o, $(ALL_OBJS)) # excludes test.o ``` **`foreach`** loops over a list: ```makefile DIRS = src lib test $(foreach DIR, $(DIRS), $(DIR)/Makefile) # expands to src/Makefile lib/Makefile test/Makefile ``` **`shell`** runs a shell command and captures output: ```makefile VERSION = $(shell git describe --tags) HOSTNAME = $(shell hostname) all: @echo "Building version $(VERSION) on $(HOSTNAME)" ``` `$(shell ...)` runs the command and uses its output. Useful for dynamic values. **`if`** for conditional expansion: ```makefile PLATFORM = $(if $(findstring Linux, $(shell uname)), linux, other) ``` `$(if condition, then, else)` expands to `then` if `condition` is non-empty, else `else`. **Chaining functions:** ```makefile SRCS = $(wildcard src/*.c) OBJS = $(patsubst src/%.c, build/%.o, $(SRCS)) ``` Read from inner to outer: `wildcard` finds `.c` files, `patsubst` transforms paths. Powerful when combined. **Performance note:** Functions like `shell` are expensive (spawn a process). Avoid calling them in hot loops or on every recipe. Use them sparingly in variable definitions (set once).