Erik Fredericks, frederer@gvsu.edu Fall 2025
Based on material provided by Erin Carrier, Austin Ferguson, and Katherine Bowers
make
Remember (assuming these files exist...): gcc main.c cool_math.c vector.c
gcc main.c cool_math.c vector.c
Or
gcc -c vector.c -o vector.o; gcc -c cool_math.c -o cool_math.o gcc main.c vector.o cool_math.o
gcc -c vector.c -o vector.o
gcc -c cool_math.c -o cool_math.o
gcc main.c vector.o cool_math.o
Makefile
make rule
rule
Makefile is a list of rules.
Format of a rule:
target: prereqs ... recipe ...
target - Name of file to create or action to perform prereqs - Files needed to create / perform target recipe - Sequence of commands to perform rule
target
prereqs
recipe
Note, recipes line start with a tab, not spaces!
To compile our example from earlier
default: main.c vector.c cool_math.c gcc -o program main.c vector.c cool_math.c
Note that running make will run the "default" rule, or the first in the file if default doesn’t exist
default: program program: main.c vector.o cool_math.o gcc -o program main.c vector.o cool_math.o vector.o: vector.c gcc -o vector.o -c vector.c cool_math.o: cool_math.c gcc -o cool_math.o -c cool_math.c
Future compilation will only recompile what’s needed! (uses file modified dates/times)
What if we want to change compilers later?
CC = gcc CFLAGS = -Wall program: main.c vector.o $(CC) $(CLFLAGS) -o program main.c vector.o
Note we access variables with $(var)
$(var)
Make gives us some handy tools:
$@ - expands to the name of the current rule $< - expands to name of first prereq $^ - expands to space-separated prereq list % - Matches a pattern that we can use later in line
$@
$<
$^
%
%.o: %.c gcc -o $@ -c $<
This generalizes our vector.o and cool_math.o from our example!
vector.o
cool_math.o
https://web.mit.edu/gnu/doc/html/make_4.html
Start with # - just like bash
#
Some rules don’t create a file, they perform an action!
The classic example is clean:
clean
clean: rm program vector.o cool_math.o
We can run this with make clean
make clean
Another common example is the install rule
install
Allows us (and others who use our code) to easily compile
Why use make over a bash script?
Newer approach: cmake