erynwells.me/content/blog/2024/make-pattern-rules/Makefile

67 lines
1.7 KiB
Makefile

# A Makefile that explores pattern and grouped rules. This Makefile expects the
# GNU version of Make.
# Relevant docs:
# https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html
# https://www.gnu.org/software/make/manual/html_node/Pattern-Match.html
# https://www.gnu.org/software/make/manual/html_node/Pattern-Intro.html
# https://www.gnu.org/software/make/manual/html_node/Multiple-Targets.html
NAMES=zip zap
.PHONY: all clean
all: $(NAMES:%=%.x) $(NAMES:%=%.y)
# Here's a simple pattern rule that generates a .txt file from a name. In this
# rule % represents the name (the 'stem' in Makefile lingo) in the targets and
# prerequisites, and $* represents the stem in the recipe.
%.txt:
@echo "=> Making $*.txt"
python -c 'print("$*!".title())' > "$@"
# Here are a couple explicit rules that generate a single file given some input
# files. Note the input files (prerequisites) will be generated with the pattern
# rule above.
zip.a : florp.txt
@echo "=> Making $@ with $<"
cat "$<" > "$@"
zap.a : bloop.txt
@echo "=> Making $@ with $<"
cat "$<" > "$@"
# This is a Grouped rule, marked with &:. It indicates that the two target files
# are produced together in one invocation of the rule, rather than two separate
# files produced by the same rule.
zip.x zip.y &: zip.a
@echo "=> Making XY files from $< with explicit rule"
echo "[X]" > zip.x
cat "$<" >> zip.x
echo "[Y]" > zip.y
cat "$<" >> zip.y
# Pattern rules with multiple targets are always Grouped, so you don't need the
# &: separator.
%.x %.y : %.a
@echo "=> Making XY files from $< with pattern rule"
echo "[X]" > $*.x
cat "$<" >> $*.x
echo "[Y]" > $*.y
cat "$<" >> $*.y
clean:
rm -f bloop.txt florp.txt
rm -f $(NAMES:%=%.a)
rm -f $(NAMES:%=%.x)
rm -f $(NAMES:%=%.y)