Intermediate · The preprocessor, multi-file programs and make · topic 39 of 60 · 25 min
Building with make
Explanation
Why make?
Typing gcc commands for ten files is tedious and error-prone, and recompiling everything after editing one file wastes time. make compares file modification times: if tax.c is newer than tax.o, it recompiles tax.c and relinks, and leaves everything else alone.
A first Makefile
# Makefile
CC = gcc
CFLAGS = -std=c17 -Wall -Wextra -g
billing: main.o tax.o invoice.o
$(CC) $(CFLAGS) main.o tax.o invoice.o -o billing
main.o: main.c tax.h invoice.h
$(CC) $(CFLAGS) -c main.c
tax.o: tax.c tax.h
$(CC) $(CFLAGS) -c tax.c
invoice.o: invoice.c invoice.h tax.h
$(CC) $(CFLAGS) -c invoice.c
.PHONY: clean
clean:
rm -f *.o billingmake # builds the first target (billing)
make clean # runs the clean recipe
make -j4 # build up to 4 targets in parallelHow make decides
- To build billing, it first makes sure main.o, tax.o and invoice.o are up to date.
- tax.o depends on tax.c and tax.h: if either is newer than tax.o (or tax.o is missing), it runs the recipe.
- If any .o changed, billing is relinked.
- Edit only tax.c → only tax.o is rebuilt and billing relinked.
Pattern rules and automatic variables
CC = gcc
CFLAGS = -std=c17 -Wall -Wextra -g
OBJS = main.o tax.o invoice.o
billing: $(OBJS)
$(CC) $(CFLAGS) $^ -o $@
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY: clean
clean:
rm -f $(OBJS) billingThe pattern rule above does not know that main.o also depends on tax.h, so editing a header might not trigger a rebuild. Real projects add automatic dependency generation (gcc -MMD -MP) or list header dependencies explicitly.
Beyond make
Larger and cross-platform projects often use CMake, which generates Makefiles (or Ninja or Visual Studio files) from a CMakeLists.txt description. You will still meet plain Makefiles everywhere in the Linux and embedded world, so knowing them pays off.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Building with make · 1/6
In this lesson you will build projects with make.
Prefer a video by a teacher? Find free videos on “makefile tutorial c beginners targets variables pattern rules” on YouTube ↗
In real life: Firmware builds in an embedded team
A team building firmware for electric-vehicle chargers uses a Makefile with a cross-compiler (CC = arm-none-eabi-gcc), separate debug and release flags, and a flash target that uploads the binary to a test board. Engineers type make flash, and only changed files are recompiled.
CC = arm-none-eabi-gcc
CFLAGS = -std=c17 -Wall -Wextra -Os -mcpu=cortex-m4 -mthumb
OBJS = main.o adc.o charger.o uart.o
charger.elf: $(OBJS)
$(CC) $(CFLAGS) $^ -T board.ld -o $@
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@Practice (0/3 done)
make prints "Makefile:4: *** missing separator. Stop." What is the most likely cause?
In a recipe for the rule app: main.o util.o, what does $^ expand to?
Write a Makefile for your money/cart/main project from the previous topic with CC and CFLAGS variables, a pattern rule for .o files, a link rule using $^ and $@, and a .PHONY clean target. Run make, touch one .c file, run make again and note which commands run. Add -MMD -MP to CFLAGS and -include $(OBJS:.o=.d) to track header dependencies.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Libraries: static and sharedThe preprocessor, multi-file programs and make · same module
- Conditional compilation and include guardsThe preprocessor, multi-file programs and make · same module
- Building real projects: CMake, warnings, debuggers and sanitizersC++ Programming (modern C++ and DSA) · Exceptions, concurrency and building projects with CMake
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
How does make decide whether to rebuild a target?
Answer: It compares modification times of the target and its prerequisites
Newer prerequisites trigger a rebuild.
What does .PHONY: clean mean?
Answer: clean is not a real file, so its recipe always runs when asked
Prevents confusion with a file named clean.
What does make -j4 do?
Answer: Runs up to 4 jobs in parallel
Parallel builds.
Which tool generates Makefiles for cross-platform projects?
Answer: CMake
CMake generates build files.
What does PUBLIC mean in target_include_directories(lib PUBLIC include)?Related
Answer: lib uses the folder AND so does anything that links lib
PUBLIC requirements propagate to consumers; PRIVATE ones do not.
From Building real projects: CMake, warnings, debuggers and sanitizers
What does gcc -c file.c produce?Related
Answer: An object file (file.o) that is not yet linked
Compile only, no linking.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “The preprocessor, multi-file programs and make” before its exam: Libraries: static and shared.
- Module 8 exam: Preprocessor, multi-file programs and make · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Bits, undefined behaviour and safety. 60 topics left in the course before the final exam.