我想要一条作为函数运行的规则,比如gzip我所有的临时目标。我在makefile中写了这些规则:
%.file0:
touch $@
%.file1: %
touch $@
%.file2: %
touch $@
%.gz: %
echo "zipping to $@"
touch $@ 我可以打电话
$ 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我的最后一个目标将被成功地压缩。然后,我可以将gzip dotted.file.file0.file1放在前面:
$ 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在给出规则%.file2之前,还将对该文件进行gzipped压缩。但我无法锁定几个目标:
$ 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. 我如何做到这一点,即对多个目标应用%.gz规则?
编辑1
从另一个角度来看,我试图以这样的方式重写我的规则:
%.file0:
touch $@
%.file1: %.gz
touch $@
%.file2: %.gz
touch $@
%.gz: %
echo "zipping to $@"
touch $@ 然后我打电话给make:
$ make -n dotted.file.file0.file1.file2 -f makefile
make: *** No rule to make target `dotted.file.file0.file1.file2'. Stop.我期望/希望gnu-make执行此命令的规则:
- 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但是,如果我只要求一条规则应用%.gz,它将在这一次起作用。
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 $@ 命令:
$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发布于 2016-08-02 12:01:53
第一个版本的问题是,您需要静态模式规则,而不是隐式规则。下面使用GNU执行任务,使用对awk的shell调用从指定的make目标构建*.file1、*.file2和*.gz目标的显式列表。它还使用foreach-eval-call组合来实例化所需的尽可能多的规则(没有菜谱),以显式地表示所有依赖关系。我必须承认,这种风格的Makefile是相当不寻常的,但你的问题也不寻常.
SUFFIXES := file1 file2 gz
# For goal $(1) and suffix $(2), build the list of all possible stems <S> such
# that $(1) matches the ^<S>\.$(2)(\..*)? regular expression. Concatenate this
# list to the $(2) make variable.
define SPLIT_rule
$(2) += $$(shell echo $(1) | awk -F.$(2) '{for(i=1;i<=NF;i++){for(j=1;j<=i;j++)printf("%s",$$$$j);printf(".$(2) ")}}')
endef
# For goal $(1), instantiate SPLIT_rule for each suffix.
define GOAL_rule
$(foreach suffix,$(SUFFIXES),$(eval $(call SPLIT_rule,$(1),$(suffix))))
endef
$(foreach goal,$(MAKECMDGOALS),$(eval $(call GOAL_rule,$(goal))))
# For suffix $(1), instantiate the static pattern rule.
define SUFFIX_rule
$$($(1)): %.$(1): %
endef
$(foreach suffix,$(SUFFIXES),$(eval $(call SUFFIX_rule,$(suffix))))
%.file0:
touch $@
%.file1: %
touch $@
%.file2: %
touch $@
%.gz: %
echo "zipping to $@"
touch $@和:
$ goal1=dotted.file.file0.file1.file2.gz
$ make -n $goal1
touch dotted.file.file0
touch dotted.file.file0.file1
touch dotted.file.file0.file1.file2
echo "zipping to dotted.file.file0.file1.file2.gz"
touch dotted.file.file0.file1.file2.gz
$ goal2=dotted.file.file0.file1.gz.file2
$ make -n $goal2
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.gz.file2
$ goal3=dotted.file.file0.file1.gz.file2.gz
$ make -n $goal3
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.gz.file2
echo "zipping to dotted.file.file0.file1.gz.file2.gz"
touch dotted.file.file0.file1.gz.file2.gz
$ goal4=dotted.file.file0.file1.file2
$ make -n $goal4
touch dotted.file.file0
touch dotted.file.file0.file1
touch dotted.file.file0.file1.file2
$ all="$goal1 $goal2 $goal3 $goal4"
$ make -n $all
touch dotted.file.file0
touch dotted.file.file0.file1
touch dotted.file.file0.file1.file2
echo "zipping to dotted.file.file0.file1.file2.gz"
touch dotted.file.file0.file1.file2.gz
echo "zipping to dotted.file.file0.file1.gz"
touch dotted.file.file0.file1.gz
touch dotted.file.file0.file1.gz.file2
echo "zipping to dotted.file.file0.file1.gz.file2.gz"
touch dotted.file.file0.file1.gz.file2.gz
make: 'dotted.file.file0.file1.file2' is up to date.注意:由于所有中间层不再是隐式的,它们不会被自动删除,就像它们在第一个版本中被声明为PRECIOUS一样。这就是为什么输出中不再有rm ...的原因。
https://stackoverflow.com/questions/38662002
复制相似问题