Make

Личный сайт Go-разработчика из Казани

A Makefile defines a graph of rules for creating a target (or targets). Its purpose is to do the minimum amount of work needed to update a target to the most recent version of the source. Famously written over a weekend by Stuart Feldman in 1976, it is still widely used (particularly on Unix and Linux) despite many competitors and criticisms.

There are many varieties of make in existence, however this article assumes that we are using GNU make which is the standard on Linux.

1# Comments can be written like this. 2 3# File should be named Makefile and then can be run as `make <target>`. 4# Otherwise we use `make -f "filename" <target>`. 5 6# Warning - only use TABS to indent in Makefiles, never spaces! 7 8#----------------------------------------------------------------------- 9# Basics 10#----------------------------------------------------------------------- 11 12# Rules are of the format 13# target: <prerequisite> 14# where prerequisites are optional. 15 16# A rule - this rule will only run if file0.txt doesn't exist. 17file0.txt: 18 echo "foo" > file0.txt 19 # Even comments in these 'recipe' sections get passed to the shell. 20 # Try `make file0.txt` or simply `make` - first rule is the default. 21 22# This rule will only run if file0.txt is newer than file1.txt. 23file1.txt: file0.txt 24 cat file0.txt > file1.txt 25 # use the same quoting rules as in the shell. 26 @cat file0.txt >> file1.txt 27 # @ stops the command from being echoed to stdout. 28 -@echo 'hello' 29 # - means that make will keep going in the case of an error. 30 # Try `make file1.txt` on the commandline. 31 32# A rule can have multiple targets and multiple prerequisites 33file2.txt file3.txt: file0.txt file1.txt 34 touch file2.txt 35 touch file3.txt 36 37# Make will complain about multiple recipes for the same rule. Empty 38# recipes don't count though and can be used to add new dependencies. 39 40#----------------------------------------------------------------------- 41# Phony Targets 42#----------------------------------------------------------------------- 43 44# A phony target. Any target that isn't a file. 45# It will never be up to date so make will always try to run it. 46all: maker process 47 48# We can declare things out of order. 49maker: 50 touch ex0.txt ex1.txt 51 52# Can avoid phony rules breaking when a real file has the same name by 53.PHONY: all maker process 54# This is a special target. There are several others. 55 56# A rule with a dependency on a phony target will always run 57ex0.txt ex1.txt: maker 58 59# Common phony targets are: all make clean install ... 60 61#----------------------------------------------------------------------- 62# Automatic Variables & Wildcards 63#----------------------------------------------------------------------- 64 65process: file*.txt #using a wildcard to match filenames 66 @echo $^ # $^ is a variable containing the list of prerequisites 67 @echo $@ # prints the target name 68 #(for multiple target rules, $@ is whichever caused the rule to run) 69 @echo $< # the first prerequisite listed 70 @echo $? # only the dependencies that are out of date 71 @echo $+ # all dependencies including duplicates (unlike normal) 72 #@echo $| # all of the 'order only' prerequisites 73 74# Even if we split up the rule dependency definitions, $^ will find them 75process: ex1.txt file0.txt 76# ex1.txt will be found but file0.txt will be deduplicated. 77 78#----------------------------------------------------------------------- 79# Patterns 80#----------------------------------------------------------------------- 81 82# Can teach make how to convert certain files into other files. 83 84%.png: %.svg 85 inkscape --export-png $^ 86 87# Pattern rules will only do anything if make decides to create the 88# target. 89 90# Directory paths are normally ignored when matching pattern rules. But 91# make will try to use the most appropriate rule available. 92small/%.png: %.svg 93 inkscape --export-png --export-dpi 30 $^ 94 95# make will use the last version for a pattern rule that it finds. 96%.png: %.svg 97 @echo this rule is chosen 98 99# However make will use the first pattern rule that can make the target 100%.png: %.ps 101 @echo this rule is not chosen if *.svg and *.ps are both present 102 103# make already has some pattern rules built-in. For instance, it knows 104# how to turn *.c files into *.o files. 105 106# Older makefiles might use suffix rules instead of pattern rules 107.png.ps: 108 @echo this rule is similar to a pattern rule. 109 110# Tell make about the suffix rule 111.SUFFIXES: .png 112 113#----------------------------------------------------------------------- 114# Variables 115#----------------------------------------------------------------------- 116# aka. macros 117 118# Variables are basically all string types 119 120name = Ted 121name2="Sarah" 122 123echo: 124 @echo $(name) 125 @echo ${name2} 126 @echo $name # This won't work, treated as $(n)ame. 127 @echo $(name3) # Unknown variables are treated as empty strings. 128 129# There are 4 places to set variables. 130# In order of priority from highest to lowest: 131# 1: commandline arguments 132# 2: Makefile 133# 3: shell environment variables - make imports these automatically. 134# 4: make has some predefined variables 135 136name4 ?= Jean 137# Only set the variable if environment variable is not already defined. 138 139override name5 = David 140# Stops commandline arguments from changing this variable. 141 142name4 +=grey 143# Append values to variable (includes a space). 144 145# Pattern-specific variable values (GNU extension). 146echo: name2 = Sara # True within the matching rule 147 # and also within its remade recursive dependencies 148 # (except it can break when your graph gets too complicated!) 149 150# Some variables defined automatically by make. 151echo_inbuilt: 152 echo $(CC) 153 echo ${CXX} 154 echo $(FC) 155 echo ${CFLAGS} 156 echo $(CPPFLAGS) 157 echo ${CXXFLAGS} 158 echo $(LDFLAGS) 159 echo ${LDLIBS} 160 161#----------------------------------------------------------------------- 162# Variables 2 163#----------------------------------------------------------------------- 164 165# The first type of variables are evaluated each time they are used. 166# This can be expensive, so a second type of variable exists which is 167# only evaluated once. (This is a GNU make extension) 168 169var := hello 170var2 ::= $(var) hello 171#:= and ::= are equivalent. 172 173# These variables are evaluated procedurally (in the order that they 174# appear), thus breaking with the rest of the language ! 175 176# This doesn't work 177var3 ::= $(var4) and good luck 178var4 ::= good night 179 180#----------------------------------------------------------------------- 181# Functions 182#----------------------------------------------------------------------- 183 184# make has lots of functions available. 185 186sourcefiles = $(wildcard *.c */*.c) 187objectfiles = $(patsubst %.c,%.o,$(sourcefiles)) 188 189# Format is $(func arg0,arg1,arg2...) 190 191# Some examples 192ls: * src/* 193 @echo $(filter %.txt, $^) 194 @echo $(notdir $^) 195 @echo $(join $(dir $^),$(notdir $^)) 196 197#----------------------------------------------------------------------- 198# Directives 199#----------------------------------------------------------------------- 200 201# Include other makefiles, useful for platform specific code 202include foo.mk 203 204sport = tennis 205# Conditional compilation 206report: 207ifeq ($(sport),tennis) 208 @echo 'game, set, match' 209else 210 @echo "They think it's all over; it is now" 211endif 212 213# There are also ifneq, ifdef, ifndef 214 215foo = true 216 217ifdef $(foo) 218bar = 'hello' 219endif

More Resources