首页 > 解决方案 > GNU make:一个模式规则中的多个目标

问题描述

有了明确的目标,我可以结合几个规则,比如

foo.o bar.o: $(SOURCES)
    cc $< -o $@

这相当于

foo.o: $(SOURCES)
    cc $< -o $@
bar.o: $(SOURCES)
    cc $< -o $@

但我想使用模式规则。

我有几个 troff 文档(man, README),我想生成.html.ascii文件。

天真的方法是

GROFF := groff
DOCS := man README

DOC_FILES = $(foreach doc,$(DOCS),$(doc).html $(doc).ascii)
CALL_GROFF = $(GROFF) -T$(subst $*.,,$@) -mman $< > $@

%.html %.ascii: %.doc
        $(CALL_GROFF)

.DEFAULT: all
all: $(DOC_FILES)

.PHONY: clean
clean:
        rm $(DOC_FILES)

但它不起作用,因为make相信所有文件都是用一个命令创建的(很像&现代make:https ://www.gnu.org/software/make/manual/html_node/Multiple-Targets.html )

显然我可以

GROFF := groff
DOCS := man README

DOC_FILES = $(foreach doc,$(DOCS),$(doc).html $(doc).ascii)
CALL_GROFF = $(GROFF) -T$(subst $*.,,$@) -mman $< > $@

%.ascii: %.doc
        $(CALL_GROFF)

%.html: %.doc
        $(CALL_GROFF)

.DEFAULT: all
all: $(DOC_FILES)

.PHONY: clean
clean:
        rm $(DOC_FILES)

但它是一种复制粘贴。

可以用 GNU make 解决吗?

标签: makefilegnu-makegrofftroff

解决方案


这正是它的工作原理;这是一个长期存在的功能。从文档中:

模式规则可能有多个目标;但是,每个目标都必须包含一个 % 字符。模式规则始终被视为分组目标(请参阅规则中的多个目标),无论它们是否使用 : 或 &: 分隔符。

如示例所述,它旨在处理在一次调用中生成多个输出的程序,例如bison. 您可以更新您的配方以一次性生成两个文件,或者像现在一样保持规则分开。


推荐阅读