I am trying to create a makefile pattern to transform the source files
articles/*/source.txt to target files
* is one and/or multiple single-level directories with unknown names.
source.txt file should when running
make generate a
target.html file in the same corresponding directory.
I was trying to use
$(wildcard article/*) to create a list of all directories i was targeting, however it seems to not be able to combine that list with a file fragment string (like
.PHONY: build SUBDIRS := $(wildcard article/*) build: $(SUBDIRS)/target.html $(SUBDIRS)/target.html: $(SUBDIRS)/source.txt echo "Generate html..." > $(SUBDIRS)/target.html
This cannot work:
article/foo article/bar article/baz. What will the above expand to? There’s no magical force in make that will see that a variable expands to multiple words, and that there’s a postfix on the variable, and append it to every word individually. Instead, the above simply expands to the variable value followed by
build: article/foo article/bar article/baz/target.html
which is clearly not what you want. Ditto for the the rule.
You want this:
build: $(addsuffix /target.html,$(SUBDIRS))
(or you could use
patsubst instead if you prefer).
When writing the rule:
you have the same problem, but the above solution still won’t give you what you want. If you use the
addsuffix here you get this:
article/foo/target.html article/bar/target.html article/baz/target.html: article/foo/source.txt article/bar/source.txt article/baz/source.txt
which will sort of work but it means the same thing as this:
article/foo/target.html: article/foo/source.txt article/bar/source.txt article/baz/source.txt article/bar/target.html: article/foo/source.txt article/bar/source.txt article/baz/source.txt article/baz/target.html: article/foo/source.txt article/bar/source.txt article/baz/source.txt
so in other words, every target file depends on ALL the source files so if any source file changes, all the targets are recreated which is probably not what you want.
As alluded to by HolyBlackCat, you want a pattern rule which gives a template for how to build one target:
make will apply this pattern rule to build each individual target.