CC Explainer
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 -lm
source.cprepro.iasm.sobj.oa.outpreproccompileassemblelink
many .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 -j
Example
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.