1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
|
# make(1)
## Anatomy of `make` rules
```make
target .. : prerequisite ..
recipe
..
```
- `target`: an output generated by the rule
- `prerequisite`: an input that is used to generate the target
- `recipe`: list of actions to generate the output from the input
> Use `make -p` to print all rules and variables (implicitly + explicitly defined).
## Pattern rules & variables
### Pattern rules
A pattern rule contains the `%` char (exactly one of them) and look like this example:
```make
%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
```
The target matches files of the pattern `%.o`, where `%` matches any none-empty
substring and other character match just them self.
The substring matched by `%` is called the `stem`.
`%` in the prerequisite stands for the matched `stem` in the target.
### Automatic variables
As targets and prerequisites in pattern rules can't be spelled explicitly in
the recipe, make provides a set of automatic variables to work with:
- `$@`: Name of the target that triggered the rule.
- `$<`: Name of the first prerequisite.
- `$^`: Names of all prerequisites (without duplicates).
- `$+`: Names of all prerequisites (with duplicates).
- `$*`: Stem of the pattern rule.
```make
# file: Makefile
all: foobar blabla
foo% bla%: aaa bbb bbb
@echo "@ = $@"
@echo "< = $<"
@echo "^ = $^"
@echo "+ = $+"
@echo "* = $*"
@echo "----"
aaa:
bbb:
```
Running above `Makefile` gives:
```text
@ = foobar
< = aaa
^ = aaa bbb
+ = aaa bbb bbb
* = bar
----
@ = blabla
< = aaa
^ = aaa bbb
+ = aaa bbb bbb
* = bla
----
```
Variables related to filesystem paths:
- `$(CURDIR)`: Path of current working dir after using `make -C path`
### Multi-line variables
```make
define my_var
@echo foo
@echo bar
endef
all:
$(my_var)
```
Running above `Makefile` gives:
```text
foo
bar
```
## Arguments
Arguments specified on the command line *override* ordinary variable
assignments in the makefile ([overriding variables][make-var-override]).
```make
VAR = abc
all:
@echo VAR=$(VAR)
```
```text
# make
VAR=abc
# make VAR=123
VAR=123
```
## Useful functions
### Substitution references
Substitute strings matching pattern in a list.
```make
in := a.o l.a c.o
out := $(in:.o=.c)
# => out = a.c l.a c.c
```
### `patsubst` ([ref][make-patsubst])
```make
in := a.c b.c
out := $(patsubst %.c, build/%.o, $(in))
# => out = build/a.o build/b.o
# This is actually equivalent to $(in:%.c=build/%.o)
```
### `filter`
Keep strings matching a pattern in a list.
```make
in := a.a b.b c.c d.d
out := $(filter %.b %.c, $(in))
# => out = b.b c.c
```
### `filter-out`
Remove strings matching a pattern from a list.
```make
in := a.a b.b c.c d.d
out := $(filter-out %.b %.c, $(in))
# => out = a.a d.d
```
### `abspath`
Resolve each file name as absolute path (don't resolve symlinks).
```make
$(abspath fname1 fname2 ..)
```
### `realpath`
Resolve each file name as canonical path.
```make
$(realpath fname1 fname2 ..)
```
### `call` ([ref][make-call])
Invoke parametrized function, which is an expression saved in a variable.
```make
swap = $(2) $(1)
all:
@echo "call swap first second -> $(call swap,first,second)"
```
Outputs:
```text
call swap first second -> second first
```
### `eval` ([ref][make-eval])
Allows to define new makefile constructs by evaluating the result of a variable
or function.
```make
define new_rule
$(1):
@echo "$(1) -> $(2)"
endef
default: rule1 rule2
$(eval $(call new_rule,rule1,foo))
$(eval $(call new_rule,rule2,bar))
```
Outputs:
```text
rule1 -> foo
rule2 -> bar
```
### foreach ([ref][make-foreach])
Repeat a piece of text for a list of values, given the syntax `$(foreach
var,list,text)`.
```make
myfn = x$(1)x
default:
@echo $(foreach V,foo bar baz,$(call myfn,$(V)))
```
Outputs:
```text
xfoox xbarx xbazx
```
## Examples
### Config based settings
```make
conf-y := default
conf-$(FOO) := $(conf-y) foo
conf-$(BAR) := $(conf-y) bar
libs-y := libdef
libs-$(FOO) += libfoo
libs-$(BAR) += libbar
all:
@echo "conf-y: $(conf-y)"
@echo "libs-y: $(libs-y)"
```
Yields the following results.
```sh
$ make
conf-y: default
libs-y: libdef
$ make FOO=y
conf-y: default foo
libs-y: libdef libfoo
$ make BAR=y
conf-y: default bar
libs-y: libdef libbar
$ make FOO=y BAR=y
conf-y: default foo bar
libs-y: libdef libfoo libbar
```
### Using `foreach / eval / call` to generate new rules
```make
define new_rule
$(1):
@echo "$(1) -> $(2)"
endef
arg-rule1 = foo
arg-rule2 = bar
RULES = rule1 rule2
all: $(RULES)
$(foreach R,$(RULES),$(eval $(call new_rule,$(R),$(arg-$(R)))))
# equivalent to
# $(eval $(call new_rule,rule1,foo))
# $(eval $(call new_rule,rule2,bar))
```
Outputs:
```text
rule1 -> foo
rule2 -> bar
```
> Use `make -R -p` to print the make database including the rules.
[make-var-override]: https://www.gnu.org/software/make/manual/html_node/Overriding.html
[make-patsubst]: https://www.gnu.org/software/make/manual/html_node/Text-Functions.html#index-patsubst-1
[make-call]: https://www.gnu.org/software/make/manual/html_node/Call-Function.html
[make-eval]: https://www.gnu.org/software/make/manual/html_node/Eval-Function.html
[make-foreach]: https://www.gnu.org/software/make/manual/html_node/Foreach-Function.html
|