aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/development/make.md
blob: 1ebe98e812aadd550117e04cdb962e8c60cf4c0b (plain) (blame)
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
# 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 & Automatic 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`

## 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
```

### `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 ..)
```

[make-var-override]: https://www.gnu.org/software/make/manual/html_node/Overriding.html