Makefile Basics — compilation pipeline - MarekBykowski/readme GitHub Wiki
The pipeline:
source.c → [preprocessor] → source.i
source.i → [compiler] → source.s (assembly)
source.s → [assembler] → source.o (object file)
source.o → [linker] → binary / .elf / .so
CC = arm-none-eabi-gcc
CFLAGS = -Wall -Wextra -O2 -mcpu=cortex-m4 -mthumb
LDFLAGS = -T linker.ld -lc
# Pattern rule — compile any .c to .o
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# Link all objects into final binary
firmware.elf: main.o uart.o mavlink.o
$(CC) $(LDFLAGS) $^ -o $@
# Useful targets
clean:
rm -f *.o *.elf
# Force rebuild if header changes
main.o: main.c uart.h mavlink.h
Key flags to know:
| Flag | Meaning |
|---|---|
-c |
compile only, don't link → produces .o |
-o |
output filename |
-Wall -Wextra |
enable warnings (always use) |
-O0 |
no optimisation (debug) |
-O2 |
optimise (production) |
-g |
include debug symbols |
-I path |
add include search path |
-L path |
add library search path |
-l name |
link library libname.a |
-D NAME |
define preprocessor macro |
-mcpu=cortex-m4 |
target CPU (embedded) |
-mthumb |
use Thumb instruction set |
-fstack-usage |
report stack usage per function |
💡 For embedded: always check
.mapfile after linking — it shows exactly where each symbol lands in flash/RAM. Critical for catching BSS/data overflows on small MCUs.