make(1)

Development tool

Reads a Makefile and only reruns the commands whose target is older than its prerequisites. The useful options: -n, -j, -B, -C, -f.

Synopsis
make [options] [target ...]

Description

make reads a file of rules, the Makefile, which says how to build each file from other files: a target, its prerequisites, then the commands, each one preceded by a tab. It looks for that file in the current directory under the names GNUmakefile, makefile, then Makefile.

With no argument, it builds the first target in the file. Before running a command, it compares modification times: a target newer than all its prerequisites is up to date, and its command is skipped. That is how only the files changed since the last build get recompiled. A target given as an argument (make clean) is built instead of the first one.

Useful options

OptionEffect
-nprints the commands that would run, without running them
-sdoes not print the commands before running them
-Brebuilds every requested target, even the ones that are up to date
-j 4runs up to four commands in parallel
-C dirchanges to dir before reading the Makefile
-f filereads file instead of Makefile
-kkeeps going with the other targets after an error

Exit status

0 when everything was built without error, 2 when an error occurred (a command that fails, a badly written Makefile). 1 only appears with the -q option, which just asks whether a target needs to be rebuilt.

Pitfalls

  • A command line that starts with spaces instead of a tab gives missing separator. cat -A Makefile shows tabs as ^I.

  • A target like clean, which does not produce a file of that name, must be declared .PHONY; otherwise a file named clean in the directory makes it “up to date” forever.

  • make only sees the dependencies written in the Makefile. A .h missing from the rules triggers no recompilation when it changes: gcc -MMD -MP generates those dependencies for you.

  • The Grademe exercise terminal does not have make. On Debian, Ubuntu or WSL, install it with sudo apt install make.

Example

Makefile
CC     = gccCFLAGS = -Wall -Wextra -gOBJ    = main.o stats.o display.o
scores: $(OBJ)	$(CC) $^ -o $@
%.o: %.c scores.h	$(CC) $(CFLAGS) -c $< -o $@
clean:	rm -f scores $(OBJ)
.PHONY: clean
Terminal
$ make -ngcc -Wall -Wextra -g -c main.c -o main.ogcc -Wall -Wextra -g -c stats.c -o stats.ogcc -Wall -Wextra -g -c display.c -o display.ogcc main.o stats.o display.o -o scores$ make -s$ ./scoresaverage: 13, best: 18$ makemake: 'scores' is up to date.$ make -B stats.ogcc -Wall -Wextra -g -c stats.c -o stats.o

make -n shows the plan without compiling anything, make -s builds silently, and the next make has nothing left to do. make -B stats.o forces a single target to be rebuilt.

Now write it yourself.