I want a rule to behave as a function, that could for instance gzip all my temporary targets. I wrote those rules in a makefile:
%.file0:
touch $@
%.file1: %
touch $@
%.file2: %
touch $@
%.gz: %
echo "zipping to $@"
touch $@
I can call
$ make -n dotted.file.file0.file1.file2.gz -f makefile
touch dotted.file.file0
touch dotted.file.file0.file1
touch dotted.file.file0.file1.file2
echo "zipping to dotted.file.file0.file1.file2.gz"
rm dotted.file.file0 dotted.file.file0.file1.file2 dotted.file.file0.file1
My last target will successfully be gzipped. I can then gzip dotted.file.file0.file1 before:
$ make -n dotted.file.file0.file1.gz.file2 -f makefile
touch dotted.file.file0
touch dotted.file.file0.file1
echo "zipping to dotted.file.file0.file1.gz"
touch dotted.file.file0.file1.gz.file2
rm dotted.file.file0 dotted.file.file0.file1.gz dotted.file.file0.file1
That file will also be gzipped before being given to the rule %.file2. But I can't gzip several targets:
$ make -n dotted.file.file0.file1.gz.file2.gz -f makefile
make: *** No rule to make target `dotted.file.file0.file1.gz.file2.gz'. Stop.
How can I do that, i.e. applying the %.gz rule on several targets?
EDIT 1
From another point of view, I tried rewriting my rules this way:
%.file0:
touch $@
%.file1: %.gz
touch $@
%.file2: %.gz
touch $@
%.gz: %
echo "zipping to $@"
touch $@
Then I call make:
$ make -n dotted.file.file0.file1.file2 -f makefile
make: *** No rule to make target `dotted.file.file0.file1.file2'. Stop.
I expect/wish gnu-make to execute the rules this order:
- ask for the file dotted.file.file0.file1.file2
- go to rule %.file2
- ask for the dependency dotted.file.file0.file1.gz
- go to rule %.gz
- as for the dependency dotted.file.file0.file1
- go to rule %.file1
- as for the dependency dotted.file.file0.gz
- go to rule %.gz
- as for the dependency dotted.file.file0
- go to rule %.file0
- create file dotted.file.file0
However if I ask only one rule to apply %.gz
, it will work this single time.
The makefile:
%.file0:
touch $@
%.file1: %.gz # !!! Notice I left this single dependency to the rule %.gz
touch $@
%.file2: % ## !!! Notice I removed the .gz here
touch $@
%.gz: %
echo "zipping to $@"
touch $@
The command:
$make -n dotted.file.file0.file1.file2 -f makefile
touch dotted.file.file0
touch dotted.file.file0.file1
echo "zipping to dotted.file.file0.file1.gz"
touch dotted.file.file0.file1.gz
touch dotted.file.file0.file1.file2
rm dotted.file.file0.file1.gz dotted.file.file0 dotted.file.file0.file1
bar.file0.file1.file2
instead ofbar.file2
)? – Betabar.file0.file1.file2
can probably be done with some effort and cleverness; buildingbar.file2
is much easier, and the name conveys exactly the same information. – Beta