# Makefile Basics **Makefile syntax** is simple: targets, prerequisites, and recipes. A target is a build product (executable, object file). Prerequisites are the files it depends on. A recipe is the command to build it. ```makefile target: prerequisite1 prerequisite2 command to build target ``` The indentation before the command must be a **tab character**, not spaces. This is a common gotcha—use `echo $'\t'` to verify a tab. **Example:** ```makefile app: main.o util.o gcc -o app main.o util.o main.o: main.c gcc -c -o main.o main.c util.o: util.c gcc -c -o util.o util.c ``` This defines three targets: `app` depends on `main.o` and `util.o`; each `.o` depends on its source `.c`. When you run `make`, Make checks timestamps and rebuilds what's out of date. **How Make works:** 1. Read the Makefile 2. Identify the target you want to build (default is the first target) 3. Check if any prerequisites are newer than the target 4. If so, recursively build the prerequisites 5. Run the recipe to build the target **Running Make:** ```bash make # build the first target (usually 'all') make app # build the 'app' target specifically make clean # run the 'clean' target (usually deletes build artifacts) make -f other.mk # use a different file (default: Makefile) ``` **Variables in recipes:** ```makefile CFLAGS = -O3 -Wall -g CC = gcc app: main.o $(CC) $(CFLAGS) -o app main.o ``` `$(VAR)` expands the variable. `CC` is the compiler, `CFLAGS` are compilation flags. Define once, use everywhere. **Automatic dependencies:** Make re-checks timestamps every build. If `main.c` is newer than `main.o`, `main.o` is rebuilt. If `main.o` is newer than `app`, `app` is rebuilt. Unchanged files skip their recipes. **Phony targets:** Not all targets produce files. `make clean` deletes files; it doesn't produce a "clean" file. Mark these as `.PHONY`: ```makefile .PHONY: clean clean: rm -f *.o app ``` Without `.PHONY`, if a file named `clean` exists, `make clean` won't run (Make thinks the target is up to date). **Comments:** Lines starting with `#` are comments. ```makefile # This is a comment app: main.o # inline comments work too gcc -o app main.o ```