我可以将什么用于特定于模式的宏的值
What can I use for the value of a pattern-specific macro
我希望特定于模式的宏的值基于模式的主干。
$(BINDIR)/%.gz: LOGFILE := %.dir/%.log
这样的事情可能吗?
不,您不能:模式 %
仅适用于规则匹配。基于 $*
的建议解决方案也并非适用于所有情况。
下面的看起来不太好,但达到了你想要的效果:
- 使用延迟评估 (
=
) 将内容评估推迟到配方执行
- 使用
$(notdir $@)
提取目标的文件名部分
- 使用
$(basename ...)
去除文件结尾
BINDIR := bin
.PHONY: all
all: $(BINDIR)/test1.gz $(BINDIR)/test2.gz
$(BINDIR)/%.gz: LOGFILE = $(basename $(notdir $@)).dir/$(basename $(notdir $@)).log
$(BINDIR)/test2.gz:
@echo "logfile for $@ is $(LOGFILE)"
$(BINDIR)/%.gz:
@echo "logfile for $@ is $(LOGFILE)"
测试运行:
$ make
logfile for bin/test1.gz is test1.dir/test1.log
logfile for bin/test2.gz is test2.dir/test2.log
为什么要混淆特定于模式的变量?一个普通的就可以了,而且启动起来更简单。
在模式规则的 recipe 中,$*
扩展为匹配规则中 %
的任何内容。 (这里我将使用静态模式规则,只是因为它们比恕我直言的普通模式规则更好。)
${BINDIR}/test1.gz ${BINDIR}/test2.gz: ${BINDIR}/%.gz:
@echo "logfile for $@ is $*.dir/$*.log"
自然地,一两个变量可以稍微整理一下:
logfile = $*.dir/$*.log
targets := $(patsubst %,${BINDIR}/test%.gz,1 2)
${targets}: ${BINDIR}/%.gz:
@echo "logfile for $@ is ${logfile}"
我希望特定于模式的宏的值基于模式的主干。
$(BINDIR)/%.gz: LOGFILE := %.dir/%.log
这样的事情可能吗?
不,您不能:模式 %
仅适用于规则匹配。基于 $*
的建议解决方案也并非适用于所有情况。
下面的看起来不太好,但达到了你想要的效果:
- 使用延迟评估 (
=
) 将内容评估推迟到配方执行 - 使用
$(notdir $@)
提取目标的文件名部分 - 使用
$(basename ...)
去除文件结尾
BINDIR := bin
.PHONY: all
all: $(BINDIR)/test1.gz $(BINDIR)/test2.gz
$(BINDIR)/%.gz: LOGFILE = $(basename $(notdir $@)).dir/$(basename $(notdir $@)).log
$(BINDIR)/test2.gz:
@echo "logfile for $@ is $(LOGFILE)"
$(BINDIR)/%.gz:
@echo "logfile for $@ is $(LOGFILE)"
测试运行:
$ make
logfile for bin/test1.gz is test1.dir/test1.log
logfile for bin/test2.gz is test2.dir/test2.log
为什么要混淆特定于模式的变量?一个普通的就可以了,而且启动起来更简单。
在模式规则的 recipe 中,$*
扩展为匹配规则中 %
的任何内容。 (这里我将使用静态模式规则,只是因为它们比恕我直言的普通模式规则更好。)
${BINDIR}/test1.gz ${BINDIR}/test2.gz: ${BINDIR}/%.gz:
@echo "logfile for $@ is $*.dir/$*.log"
自然地,一两个变量可以稍微整理一下:
logfile = $*.dir/$*.log
targets := $(patsubst %,${BINDIR}/test%.gz,1 2)
${targets}: ${BINDIR}/%.gz:
@echo "logfile for $@ is ${logfile}"