make
What is Make?
Make is a build tool, which reads rules from a makefile.
A rule looks like this:
target: prerequisites
recipeIf the prerequisite files are newer than the target, make will run the recipe to rebuild the target.
There is a TAB before the recipe.
The prerequisite files can be both data and code.
If the target is a directory, the timestamp is NOT automatically updated when files are copied into it. Thus the last step is usually
touch $@.Make prints actions as it executes them. Using
@at the start of an action tells Make not to print this action. Therefore usually there is a@beforeecho.
Automatic Variable
$@: the target of the current rule.$^: the dependencies of the current rule.$<: the first dependency of the current rule.
Common usages
make: builds the first target in makefile.make target1: searches the rule fortarget1and builds it.make clean: usuallycleanis a phony target, which removes all temporary files.
Options
-f: read from other files than makefile, e.g.make -f common.mk.-n: dry run - show the commands it will execute without actually running them.-C: change the directory and then run make.
With the following rule, make clean will run the recipe regardless of whether there is a file named clean.
.PHONY: clean
clean:
rm *.o tempA real example
With the following makefile, run make to remake all three programs, or specify as arguments the ones to remake (e.g. make prog1 prog3).
all : prog1 prog2 prog3
.PHONY : all
prog1 : prog1.o utils.o
cc -o prog1 prog1.o utils.o
prog2 : prog2.o
cc -o prog2 prog2.o
prog3 : prog3.o sort.o utils.o
cc -o prog3 prog3.o sort.o utils.oUse phony target as subroutine
When one phony target is a prerequisite of another, it serves as a subroutine of the other. With the following makefile, make cleanall will delete the object files, the difference files, and the file program.
.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff
rm program
cleanobj :
rm *.o
cleandiff :
rm *.diffPattern Rules
%.dat : books/%.txt countwords.py
python countwords.py $< $*.dat # can also use $@ hereThis rule can be interpreted as: “In order to build a file named [something].dat (the target) find a file named books/[that same something].txt (the dependency) and run countwords.py [the dependency] [the target].”
The Make % wildcard can only be used in a target and in its dependencies. It cannot be used in actions. In actions, you may however use $*, which will be replaced by the stem with which the rule matched.
Advanced Topics
Variables/Macros
Variables make the makefile more readable. For example:
CC = gcc # variable assignment
CCFLAGS = -Wall -Wextra -Werror -std=c99 -pedantic -g
main: main.o moreCode.o
$(CC) $(CCFLAGS) -o main main.o moreCode.o # variable referenceWe could also separate configuration from computation: use include config.mk at the top of the main makefile and put all configuration (LANGUAGE, SRC_FILE_NAME, etc) in config.mk.
Variables can be overridden on command line. e.g.
#Makefile
TEXT = default
target1:
@ echo $(TEXT)
$ make
default
$ make TEXT=abc
abcFunctions
Use wildcard function to get lists of files matching a pattern. Use patsubst function to rewrite file names.
TXT_FILES=$(wildcard books/*.txt)
DAT_FILES=$(patsubst books/%.txt, %.dat, $(TXT_FILES))
# output
TXT_FILES: books/abyss.txt books/isles.txt books/last.txt books/sierra.txt
DAT_FILES: abyss.dat isles.dat last.dat sierra.datSelf-Documenting Makefile
Add a comment that begins with ## before each block and add a help block in the makefile. For example:
# makefile
## clean : Remove auto-generated files.
.PHONY : clean
clean :
rm -f $(DAT_FILES)
rm -f results.txt
.PHONY : help
help : makefile
@sed -n 's/^##//p' $<```And in terminal we could run make help:
$ make help
clean : Remove auto-generated files.References
Last updated
Was this helpful?