Reputation: 1089
I'm missing something about implicit rules. Here's the Makefile (GNU Make 4.2.1)
heimdall /tmp 1670> cat Makefile
PARTS= a b c
.SECONDEXPANSION:
data/events2: $$(patsubst %,$$(@D)/%.ppd,$(PARTS))
/bin/ls -l $^
%/events2: $$(patsubst %,$$(@D)/%.ppd,$(PARTS))
/bin/ls -l $^
Here are the cooked up data to illustrate the situation:
heimdall /tmp 1671> ls -1 data data1
data:
a.ppd
b.ppd
c.ppd
data1:
a.ppd
b.ppd
c.ppd
Here is make
using an explicit rule, which works like I'd expect.
heimdall /tmp 1672> make data/events2
/bin/ls -l data/a.ppd data/b.ppd data/c.ppd
-rw-rw-r-- 1 bennett None 0 Feb 4 12:19 data/a.ppd
-rw-rw-r-- 1 bennett None 0 Feb 4 12:19 data/b.ppd
-rw-rw-r-- 1 bennett None 0 Feb 4 12:19 data/c.ppd
And finally, this:
heimdall /tmp 1673> make data1/events2
make: *** No rule to make target 'data1/events2'. Stop.
Why doesn't the implicit rule match? I feel like I've missed something fundamental.
Thanks.
-E
Upvotes: 0
Views: 86
Reputation: 9664
%/events2: $$(patsubst %,$$(@D)/%.ppd,$(PARTS))
Is not a pattern rule that would match in your sample structure. From the docs:
%
in a prerequisite of a pattern rule stands for the same stem that was matched by the%
in the target. In order for the pattern rule to apply, its target pattern must match the file name under consideration and all of its prerequisites (after pattern substitution) must name files that exist or can be made. These files become prerequisites of the target.
However in your target %
would be matching data1
. But there isn't actually any %
to match on prerequisite side as those present are oft patsubst
function and directory (stem) is referred to as $(@D)
.
I've tried to write such rule like this using foreach
function:
%/events2: $(foreach part,$(PARTS), %/$(part).ppd)
/bin/ls -l $^
If you wanted to stick with patsubst
, this should work as well:
%/events2: $(patsubst %,\%/%.ppd,$(PARTS))
/bin/ls -l $^
Not that %
is used for directory name matching the one in target and it's escaped with \
to make it through patsubst
unscathed.
Either way seems to have gone well with GNU make yielding:
$ make data1/events2
/bin/ls -l data1/a.ppd data1/b.ppd data1/c.ppd
-rw-r--r-- 1 ondrej users 0 Feb 4 22:00 data1/a.ppd
-rw-r--r-- 1 ondrej users 0 Feb 4 22:00 data1/b.ppd
-rw-r--r-- 1 ondrej users 0 Feb 4 22:00 data1/c.ppd
Upvotes: 1