Reputation: 15
I tried to build a nested directories following: Iterating through a list of directories in a Makefile
Here is my script
LAYER1 = a b
LAYER2 = 1 2
$(LAYER1)/foo%/run: $(DIR)
mkdir -p $@
DIR: $(addsuffix /foo$(LAYER2)/run, $(LAYER1))
The expected output is creating a/foo1/run a/foo2/run b/foo1/run b/foo2/run but the output is only 1 directory named a. How do I create the expected directory structure?
Upvotes: 0
Views: 268
Reputation: 6387
See MadScientist's answer as to why your answer would not work. As far as something that will work, you likely want code that looks like this:
LAYER1 = a b
LAYER2 = 1 2
DIRS := $(foreach L1,$(LAYER1),\
$(foreach L2,$(LAYER2),\
$(L1)/foo$(L2)/run))
all: | $(DIRS)
$(DIRS):
mkdir -p $@
Notice the use of order-only dependencies as the prerequisite type for $(DIRS)
Upvotes: 0
Reputation: 101051
What does the rule:
$(LAYER1)/foo%/run: $(DIR)
expand to? It expands to this:
a b/foo%/run: $(DIR)
(I don't know what $(DIR)
is supposed to be) which is an explicit rule that tells make how to build two things: a
and b/foo%/run
(this is not a pattern rule because not all the targets contain %
).
Since a
here is the first target in the makefile, it's the one that will be run by default when you run make
.
What does $(addsuffix /foo$(LAYER2)/run, $(LAYER1))
do? It takes every word in $(LAYER1)
and prefixes it by the string /foo$(LAYER2)/run
. What is that string? It's /foo1 2/run
. So the result of this is:
a/foo1 2/run b/foo1 2/run
which means DIR
has the files a/foo1
, 2/run
, b/foo1
, and 2/run
as dependencies.
If LAYER1
has multiple words you need to loop through it, not just use it as-is.
Upvotes: 3