C · 6 · Advanced / Job-Ready33 / 35 · 94%
make, CMake & Multi-File Projects
Split code into translation units and rebuild only what changed.
Examples: Makefile, CMakeLists.txt, -I -L -l
shortcuts: ← prev · → next · M mark
1
Compile vs Link
Each .c becomes a .o; the linker resolves symbols between them.
Syntax
syntax
gcc -c main.c -o main.o
gcc -c util.c -o util.o
gcc main.o util.o -o app -lmmany .c → many .o → one binary
2
A Real Makefile
Pattern rules plus dependency generation.
Example
Makefile — recipe lines must start with a TAB
CC := gcc
CFLAGS := -Wall -Wextra -O2 -MMD -MP
OBJS := main.o util.o
app: $(OBJS)
$(CC) $(OBJS) -o $@ -lm
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
-include $(OBJS:.o=.d)
clean:
rm -f app $(OBJS) $(OBJS:.o=.d)3
CMake
Generates the build files, handles dependencies and platforms for you.
Syntax
syntax
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -jExample
CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(app C)
set(CMAKE_C_STANDARD 11)
add_executable(app main.c util.c)
target_compile_options(app PRIVATE -Wall -Wextra)
target_link_libraries(app PRIVATE m)4
Linker Errors Decoded
The two messages every C developer meets.
Common pitfalls
- ✕"undefined reference to X" — you declared X but never linked the object/library defining it.
- ✕"multiple definition of X" — a variable or function body was defined in a header included twice.
- ✕Library order matters with static libs: put -lfoo AFTER the objects that use it.