Rules
Table of Contents
- Define targets with recursive wildcards
- Manage background processes
- Multiple Rules for One Target
- Double-Colon(
::
) Rules - Implicit Rules(Pattern Rules) vs Static Pattern Rules
- Why exported variables in Makefile is not received by executable?
- Split Recipe Lines
- What if multiple pattern rules match a target?
- What is
stem
in Pattern Rules - Automatic Prerequisites, Auto-Dependency Generation
- Chained Rules
- Special Recipe Prefixes(
@echo
,-rm
, etc) - Can I define a pattern rule with no recipe
Define targets with recursive wildcards howto
$(wildcard pattern)
does not support recursive search.- Use
$(shell find 'dir' -type f -name '*.txt')
Manage background processes howto
- Write a pid file when running a background process using shell's
$!
- Clean up the process on stop
test: db
pipenv run pytest
db: db.pid
db.pid:
sls dynamodb start &> 'db.log' & echo "$$!" > 'db.pid'
db-stop: PID = $(shell cat db.pid)
db-stop: PGID = $(shell ps -o pgid= $(PID))
db-stop:
-kill -INT -$(PGID)
-rm 'db.pid'
Multiple Rules for One Target discussion
- One file can be the target of several rules.
- All the prerequisites mentioned in all the rules are merged into one list of prerequisites for the target.
- To define rules on the same target independently, use double-colon rules(
::
) - There can only be one recipe to be executed for a file.
For using prerequisites in recipes, you need to use $<
or $+
:
$<
and$+
are both for the list of prerequisites, while$<
is a kind of a deduped version.- It appears that prerequisites of these both variables are ordered in the way they were listed in the makefile.
Double-Colon(::
) Rules discussion
- When a target appears in multiple rules, all the rules must be the same type: all ordinary, or all double-colon.
- If they are double-colon, each of them is independent of the others.
- Each double-colon rule’s recipe is executed if the target is older than any prerequisites of that rule.
- If there are no prerequisites for that rule, its recipe is always executed.
Implicit Rules(Pattern Rules) vs Static Pattern Rules discussion
The difference with Implicit Rules is in how make
decides when the rule applies:
- Implicit Rules
-
- An implicit rule can apply to any target that matches its pattern
- It does apply only when the target has no recipe otherwise specified, and only when the prerequisites can be found.
- Static Pattern Rules
-
- A static pattern rule applies to the precise list of targets that you specify in the rule.
- It cannot apply to any other target and it invariably does apply to each of the targets specified.
Why exported variables in Makefile is not received by executable? discussion
- It's because each line in a
Makefile
is a separate shell-process. - Join recipe lines with
;
,&&
and the like, followed by\
.
Split Recipe Lines howto
- Place
\
before each newline
What if multiple pattern rules match a target? discussion
3.81
or beforemake
would choose the first rule(in the order the rule is defined in Makefile)
- From
3.82
make
would choose the shortest stem pattern rule.- This produces the usually-desired behavior where more specific patterns are preferred.
What is stem
in Pattern Rules discussion
stem
is matched portion of the rule:
all: sub/foo.x
# if matched, 'sub/foo' is the stem
%.x:
@echo "$*"
# if matched, 'foo' is the stem
sub/%.x:
@echo "$*"
Automatic Prerequisites, Auto-Dependency Generation discussion
In my opinion, it is somewhat complicated and there are a lot of tricky parts. Consider only using this pattern when you are sure that it is of huge benefit.
Chained Rules discussion
make
tries to make targets with chained rules. For example,n.y
->n.c
->n.o
.- In this case,
n.c
is an intermediate file. - When running
make n.o
andn.c
does not exist,make
first tries to maken.c
fromn.y
. Once everything is done,make
deletesn.y
. - You can modify this behavior with
.SECONDARY
and.INTERMEDIATE
special targets. make
cannot chain the same pattern rules.
Special Recipe Prefixes(@echo
, -rm
, etc) discussion
@
- suppresses the normal echo of the command that is executed.
-
- ignores the exit status of the command that is executed. Normally, a non-zero exit status would stop that part of the build.
+
forcefully executes the command even under non-executing options like:
-n
for doing nothing, just print-t
fortouch
-q
for question of whether there is needed to be updated.
Can I define a pattern rule with no recipe discussion
No. When you define a pattern rule with no recipe, it means just canceling implicit rules related to the pattern. It does not mean adding any dependencies.