Makefile (notes and examples) This document explains how to compile C programs with gcc and how to use Makefiles to automate builds. It includes step-by-step commands, split compilation, simple Makefiles, and improved templates with variables and pattern rules.
1. How to compile a simple program
Create main.c:
Write this example code into main.c:
1 2 3 gcc -o hello main.o defs.o gcc -c main.c -o main.o
Makefile (notes and examples) This document explains how to compile C programs with gcc and how to use Makefiles to automate builds. It includes step-by-step commands, split compilation, simple Makefiles, and improved templates with variables and pattern rules.
1. How to compile a simple program
Create main.c:
Write this example code into main.c:
1 2 3 4 5 6 7 #include <stdio.h> int main (int argc, char **argv) { printf ("Hello, World!\n" ); return 0 ; }
Compile with gcc:
Run the produced executable (default name is a.out):
2. Build and rename the program Compile and set the output name with -o:
Run:
3. Step-by-step compilation stages
Preprocess (.i):
Compile to assembly (.s):
Assemble to object code (.o):
Link to executable:
Run:
4. Compile multiple source files (example)
Create three files:
1 touch main.c defs.h defs.c
Example main.c:
1 2 3 4 5 6 7 8 9 10 #include <stdio.h> #include "defs.h" int main (int argc, char **argv) { int a = 2 , b = 3 ; printf ("Hello, World!\n" ); printf ("%d+%d=%d\n" , a, b, add(a, b)); return 0 ; }
defs.h:
1 2 3 4 5 6 #ifndef DEFS_H #define DEFS_H int add (int a, int b) ;#endif
defs.c:
1 2 3 4 5 6 #include "defs.h" int add (int a, int b) { return a + b; }
Compile defs.c to an object file:
Compile main.c to an object file and link both:
1 2 gcc -c main.c -o main.o gcc -o hello main.o defs.o
Run:
5. Split compilation (separate compile and link)
Compile each source to object files:
1 2 gcc -c defs.c -o defs.o gcc -c main.c -o main.o
Link objects into the final executable:
1 gcc -o hello main.o defs.o
6. Using a simple Makefile Create a file named Makefile (or makefile) with this content:
1 2 3 4 5 all: gcc -o hello -s main.c clean: rm -f ./hello
Run:
1 2 3 make all ./hello make clean
7. Makefile for multiple sources Simple inline rule:
1 2 3 4 5 all: gcc -o hello -s main.c defs.c clean: rm -f ./hello
Better: explicit object rules and variables
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 CC = gcc CFLAGS = -Wall -g TARGET = hello OBJS = main.o defs.o $(TARGET) : $(OBJS) $(CC) $(CFLAGS) -o $(TARGET) $(OBJS) main.o: main.c defs.h $(CC) $(CFLAGS) -c main.c -o main.o defs.o: defs.c defs.h $(CC) $(CFLAGS) -c defs.c -o defs.o .PHONY : cleanclean: rm -f $(OBJS) $(TARGET)
Notes:
Use $(CC) and $(CFLAGS) so you can change compiler/flags in one place.
Declare clean as .PHONY to ensure make runs the rule and not treat it as a file.
8. Pattern rules and directories (template) This template builds into bin/ and obj/ directories using pattern rules:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 CC = gcc CFLAGS = -Wall -g TARGET = bin/hello SRC = src/main.c src/defs.c OBJS = $(SRC:src/%.c=obj/%.o) $(TARGET) : $(OBJS) @mkdir -p $(dir $@ ) $(CC) $(CFLAGS) -o $@ $(OBJS) obj/%.o: src/%.c include/defs.h @mkdir -p $(dir $@ ) $(CC) $(CFLAGS) -c $< -o $@ .PHONY : cleanclean: rm -rf obj bin
Fixes and additions in this document:
Corrected typos and command names.
Standardized code-block languages for readability.
Added variable examples (CC, CFLAGS, TARGET, OBJS).
Included pattern-rule example for building object files into a separate directory.
Quick tips:
Use make -n to dry-run and see the commands make would execute.
Use make -jN to run N jobs in parallel (e.g., make -j4).
Keep header dependencies up-to-date; consider using gcc -M or tools like makedepend for large projects.
End of notes.