Makefile

Makefile is the declarative language for the make(1) build system. The syntax should be written to a file named Makefile.


Rules

A rule has three components: a target, 0 or more prerequisites, and 0 or more recipes.

hello: hello.cpp
    g++ -o hello hello.cpp

hello is a target. With this Makefile in the working directory, it can be built by calling make hello in a terminal.

hello.cpp is a prerequisite. There can be any number of prerequisites; anything after the colon on the target line is treated as one. Before hello can be built, this prerequisite must be satisfied by either...

The remainder is a recipe. Every tabbed, newline-delimited line following a target line is a recipe. Each recipe is run in a discrete subprocess.

Noisy Rules

When executing a rule, each recipe is printed to the terminal before the recipe is executed. This can improve debugging. This can also create an extremely noisy terminal.

To make a recipe not print before executing, prefix it with @.

To make a recipe silent, redirect the output (i.e. >/dev/null 2>&1).

If errors can be ignored, consider adding || true to the end.

Variables in Rules

To access an environment variable, prefix with two dolar signs ($$).

demo:
    for number in 1 2 3 4; do \
        echo $$number; \
    done

Each recipe is executed in a discrete subprocess. As such, changes to environment variables disappear after execution.

demo:
    @export DEMO="YES"
    echo "Do variables carry over between recipes? $${DEMO:-NO}!"

This will print Do variables carry over between recipes? NO!.


Phony Rules

make(1) can also be used to automate processes that aren't necessarily about making a file.

A common example is a clean rule.

.PHONY: clean
clean:
    rm -f hello

The .PHONY component ensures that make(1) does not look for a clean file. If there were such a file, make(1) might short circuit; it would believe that the rule is already satisfied.


Pattern Rules

Many programs have a generic and abstract-able build process. Consider the following:

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

For any foo.o file, make(1) knows that it can be built with cc -c foo.c -o foo.o.

Automatic Variables

Automatic variables are critical to making use of pattern rules. These are populated for every rule.

Variable

Contents

$@

file name of the target

$^

names of all the prerequisites, with spaces between them

$<

name of the first prerequisite

$?

names of all the prerequisites that are newer than the target, with spaces between them


See also

Make

GNU make manual


CategoryRicottone

Make/Makefile (last edited 2023-05-31 16:27:12 by DominicRicottone)