My makefile:
./corpus/%.spacy : ./assets/%.json
python3 ./scripts/convert.py $< $@
Two questions:
Even if A.spacy and A.json exist and A.json is updated more recently than A.spacy, I get the following output.
$ make $ make: *** No targets. Stop.
What to add to have it make A.spacy if only A.json exists? I tried the below code, which didn't work and I feel I'm not fully understanding targets and dependencies in makefiles.
convert : ./corpus/%.spacy python3 ./scripts/convert.py $(./scripts/$*.json) $< ./corpus/%.spacy: ./assets/%.json echo $?
Didn't work as in gave the following output
$ make convert
$ make: *** No rule to make target `corpus/%.spacy', needed by `convert'. Stop.
CodePudding user response:
You seem to be thinking that declaring a pattern rule will cause make to go spelunking your directory looking for all possible ways to use that pattern, as if it were a wildcard or something akin to ls *.spacy
.
That's not what a pattern rule is.
A pattern rule is a template that make can apply if it wants to build a given target and it doesn't know how to build that target.
If you have the above makefile it just tells make "hey, if you happened to want to create a target that matches the pattern ./corpus/%.spacy
then here's a way to do it". If you type make
with no arguments, then you haven't told make that you want to build anything so it won't use your pattern rule.
If you type:
$ make ./corpus/A.spacy
now you've told make you want to actually build something (./corpus/A.spacy
), so now make will try to build that thing, and it will see your pattern rule and it will try to use it.
As for the other, this:
convert : ./corpus/%.spacy
python3 ./scripts/convert.py $(./scripts/$*.json) $<
is not a pattern rule. A pattern rule must have a pattern character (%
) in the target; this is defining a target convert
that depends on a file named, explicitly, ./corpus/%.spacy
of which you don't have any file with that name, so you get that error.
You didn't actually describe what you wanted to do, but I think maybe you want to do something like this:
# Find all the .json files
JSONS := $(wildcard ./corpus/*.json)
# Now figure out all the output files we want
SPACYS := $(patsubst ./corpus/%.json,./corpus/%.spacy,$(JSONS))
# Now create a target that depends on the stuff we want to create
all: $(SPACYS)
# And here's a pattern that tells make how to create ONE spacy file:
./corpus/%.spacy : ./assets/%.json
python3 ./scripts/convert.py $< $@