GNU Makefiles

Last Modified: 02/23/2025 09:35AM GMT+0

This page contains a summarization and verbatim of most parts from the official GNU online document.

I put this up to easily use as a reference for GNU Make so only the parts that I deem important will be documented.

Please refer to the official docs for a more thorough guide on GNU Make.

Enjoy!

Make #

The make utility automatically determines which pieces of a large program need to be recompiled and issues commands to recompile them.

A Makefile tells make how to compile and link a program.

Rules #

A simple Makefile consists of rules with the ff. shape:

target ... : prerequisites ...
recipe
...
...

A target is usually a name of a file that is generated by a program; examples of targets are executables or object files. A target can also be a name of an action to be carried out, such as clean (see Phony targets).

Targets that do not refer to files but only run actions are called phony targets.

A prerequisite is a file that is used as input to create the target. A target often depends on several files.

A recipe is an action that make carries out. A recipe may have more than one command, either on the same line or on each of its own line.

Please note: That a tab character is necessary at the beginning of every recipe line!

Usually a recipe is in a rule with prerequisites and serves to create a target file if any other prerequisites change. However, the rule that specifies a recipe for the target need not have any prerequisites.

A rule, then, explains how and when to remake certain files which are the targets of a particular rule.

make carries out the recipe on the prerequisites to create or update the target.

A rule can also explain how and when to carry out an action.

A simple Makefile #

exe: main.o module_a.o module_b.o module_c.o
cc -o exe main.o module_a.o module_b.o module_c.o

main.o: main.c defs.h
cc -c main.c

module_a.o: module_a.c module_a.h
cc -c module_a.c

module_b.o: module_b.c module_b.h
cc -c module_b.c

module_c.o: module_c.c module_c.h
cc -c module_c.c

# Clean is a phony target that only runs a recipe
clean:
rm exe main.o module_a.o module_b.o module_c.o

How make processes a Makefile #

By default, make starts with the very first target (not targets whose names starts with ., unless they contain one or more /). This is called the default goal.

Goals are targets that make strives to ultimately update. This can be overriden.

Variables in Makefiles #

Variables in Makefiles allow text strings to be substituted throughout the file.

To define a variable:

objects = main.o module_a.o module_b.o module_c.o

To use a variable, express the variable like so $(variable):

objects = main.o module_a.o module_b.o module_c.o

exe: $(objects)
cc -o exe $(objects)

main.o: main.c defs.h
cc -c main.c

module_a.o: module_a.c module_a.h
cc -c module_a.c

module_b.o: module_b.c module_b.h
cc -c module_b.c

module_c.o: module_c.c module_c.h
cc -c module_c.c

clean:
rm exe $(objects)

Letting make deduce the recipes #

Make can implicitly compile object files based on their target names.

For example, make will automatically generate the recipe cc -c main.c -o main.o if the target name is provided as main.o, it will also implicitly provide main.c as one of the prerequisites.

This way we can omit certain values within the recipes and prerequisites sections.

objects = main.o module_a.o module_b.o module_c.o

exe: $(objects)
cc -o exe $(objects)

module_a.o: module_a.h

module_b.o: module_b.h

module_c.o: module_c.h

clean:
rm exe $(objects)