Reputation: 153
I have the following makefile:
all: DIR/0/a.txt DIR/1/b.txt DIR/2/c.txt DIR/3/abc.txt
DIR/%/abc.txt: DIR/%/def.xtx # rule #1
mkdir -p $(@D)
touch $@
DIR/%.txt: # rule #2
mkdir -p $(@D)
touch $@
DIR/%.xtx:
touch $@
I want to generate DIR/%/def.xtx
whenever DIR/%/abc.txt
is generated; otherwise generate only DIR/%.txt
.
Using the makefile above with GNU Make 3.81 however, only DIR/3/abc.txt
gets generated and DIR/%/def.xtx
is not generated.
Following the "Implicit rule search algorithm" in the GNU make user manual we get:
(1) Split t into a directory part, called d, and the rest, called n. For example, if t is ‘src/foo.o’, then d is ‘src/’ and n is ‘foo.o’.
For DIR/3/abc.txt
, d = DIR/3
and n = abc.txt
.
(2) Make a list of all the pattern rules one of whose targets matches t or n. If the target pattern contains a slash, it is matched against t; otherwise, against n.
Rules #1 and #2 match.
(3) If any rule in that list is not a match-anything rule, then remove all nonterminal match-anything rules from the list.
NOT SURE: no rule is removed from the list.
(4) Remove from the list all rules with no recipe.
No rule is removed.
(5) For each pattern rule in the list:
(5.a) Find the stem s, which is the nonempty part of t or n matched by the ‘%’ in the target pattern.
For rule #1, s = 3
.
For rule #2, s = 3/abc
(5.b) Compute the prerequisite names by substituting s for ‘%’; if the target pattern does not contain a slash, append d to the front of each prerequisite name.
For rule #1, it becomes: DIR/3/abc.txt: DIR/3/def.xtx
Rule #2 has no prerequisites.
(5.c) Test whether all the prerequisites exist or ought to exist. (If a file name is mentioned in the makefile as a target or as an explicit prerequisite, then we say it ought to exist.)
NOT SURE: DIR/3/def.xtx
is mentioned by the rule DIR/%.xtx:
.
After this long long long explanation, my opinion is that I am probably wrong in (5.c).
Upvotes: 2
Views: 5082
Reputation: 99172
From the manual,
A rule whose prerequisites actually exist or are mentioned always takes priority over a rule with prerequisites that must be made by chaining other implicit rules.
Your rule #1 requires chaining, your rule #2 has no prerequisites, so Make will choose #2 over #1 when trying to build DIR/3/abc.txt
.
EDIT:
If you can stand having a list of directories:
DIRS := DIR/0 DIR/1 DIR/2 DIR/3
then you can do it with a static pattern rule:
all: DIR/0/a.txt DIR/1/b.txt DIR/2/c.txt DIR/3/abc.txt
ABC_TXT := $(addsuffix /abc.txt, $(DIRS))
$(ABC_TXT): DIR/%/abc.txt : DIR/%/def.xtx
DIR/%.txt:
mkdir -p $(@D)
touch $@
DIR/%.xtx:
touch $@
(And it avoids duplication of the .txt
rule too!)
Upvotes: 4