What’s a Makefile?

GNU Make is a tool that’s used to create executables and other non-source files from a program's source files. For example, we use it to generate our OBC-firmware.out executable which is then flashed onto the RM46 microcontroller.

Make uses a Makefile to learn how to build the program. The Makefile lists all the non-source files (including the executable) and the steps to generate them from the source files. When you write a program, you can write a Makefile for it, so you can use GNU Make to automatically build the program.

If you’re interested in how a C source file gets turned into an executable, take a look at the C compilation process here.

To install Make on Ubuntu, try:

sudo apt-get update
sudo apt-get install build-essential # Installs make, along with some other tools
make -version # Should return the version of make if installed correctly

Example Makefile

This is the Makefile we’ll be dissecting in the following sections.

CC = gcc # gcc is a compiler by the GNU Project
CFLAGS = -g -Wall # These are build flags which enable certain compiler functionality

HEADERS = program.h headers.h # Include files that we're dependent on
OBJECTS = program.o # Object files that we're dependent on

.PHONY: all
all: hello-world.out

.PHONY: hello-world.out
hello-world.out: $(OBJECTS)
	$(CC) $(OBJECTS) -o $@

%.o: %.c $(HEADERS)
	$(CC)-c $< -o $@

.PHONY: clean
clean:
	-rm -f $(OBJECTS)
	-rm -f hello-world.out

Variables

One way to assign a value to a variable in a Makefile is with the = operator. There are some other operators, like := and ?=, which are slightly different. We’ll ignore these for now though.

CC = gcc # gcc is a compiler by the GNU Project
CFLAGS = -g -Wall # These are build flags which enable certain compiler functionality

HEADERS = program.h headers.h # Include files that we're dependent on
OBJECTS = program.o # Object files that we're dependent on

To use any of these variables throughout the Makefile, you can use the $ operator. For example, if you’d like to use the CC variable, then you can write $(CC)

Automatic Variables

Make has some automatic variables that you can see are used throughout the Makefile. Here’s what some of them mean:

Targets and Dependencies