Makefile中的通配符目标

64

我该如何压缩以下的Makefile目标?

$(GRAPHDIR)/Complex.png: $(GRAPHDIR)/Complex.dot
        dot $(GRAPHDIR)/Complex.dot -Tpng -o $(GRAPHDIR)/Complex.png

$(GRAPHDIR)/Simple.png: $(GRAPHDIR)/Simple.dot
        dot $(GRAPHDIR)/Simple.dot -Tpng -o $(GRAPHDIR)/Simple.png

$(GRAPHDIR)/IFileReader.png: $(GRAPHDIR)/IFileReader.dot
        dot $(GRAPHDIR)/IFileReader.dot -Tpng -o $(GRAPHDIR)/IFileReader.png

$(GRAPHDIR)/McCabe-linear.png: $(GRAPHDIR)/McCabe-linear.dot
        dot $(GRAPHDIR)/McCabe-linear.dot -Tpng -o $(GRAPHDIR)/McCabe-linear.png

graphs: $(GRAPHDIR)/Complex.png $(GRAPHDIR)/Simple.png $(GRAPHDIR)/IFileReader.png $(GRAPHDIR)/McCabe-linear.png

--

使用 GNU Make 3.81

3个回答

78

这个概念被称为模式规则。您可以在GNU make手册中了解它。

$(GRAPHDIR)/%.png: $(GRAPHDIR)/%.dot
        dot $< -Tpng -o $@

graphs: $(patsubst %,$(GRAPHDIR)/%.png, Complex Simple IFileReader McCabe)\

或者只是

%.png: %.dot
        dot $< -Tpng -o $@

graphs: $(patsubst %,$(GRAPHDIR)/%.png, Complex Simple IFileReader McCabe)

您还可以通过将其中一个模式提取到单独的变量PNG_PATTERN中来消除所有重复,如下所示:

PNG_pattern=$(GRAPHDIR)/%.png

$(PNG_pattern): $(GRAPHDIR)/%.dot
        dot $< -Tpng -o $@

graphs: $(patsubst %,$(PNG_pattern), Complex Simple IFileReader McCabe)

1
@Beta,嗯,不知道。我通常处理的情况是处理特定目录,所以我已经习惯了这种方式。 :) - P Shved
1
“高级内容”被添加到“或者只是”之前(在“或者只是”部分中没有重复,我真的很努力找到)。 - ShreevatsaR
@ShreevatsaR 好的,我稍微编辑了一下帖子 :-) 顺便说一句,哇,我还记得你,几年前我们在这里讨论算法。你现在在忙什么呢?=) - P Shved
哈哈,是的,我也记得你的名字;是的,在 Stack Overflow 的早期,这里有更多的算法问题,并且节奏可以跟上,我也是一名学生或刚毕业不久的人,有更多的时间和兴趣。现在我不确定自己在做什么了 :-)(官方上说我是一名软件工程师,但是……)希望你一切都好! - ShreevatsaR

28

如果您确实希望为当前目录中的每个.DOT生成一个.PNG:

%.png : %.dot
    dot -Tpng -o $@ $<

all: $(addsuffix .png, $(basename $(wildcard *.dot)))

在阅读@Pavel的答案后,我想出了这个Makefile。


basename会剪切掉GRAPHDIR吗? - monokrome
2
从文档中提取:"$(basename names…) 提取names中每个文件名的除后缀外的所有内容。如果文件名包含句点,则基本名称是从开头到(但不包括)最后一个句点的所有内容。目录部分中的句点将被忽略。如果没有句点,则基本名称是整个文件名。例如, $(basename src / foo.c src-1.0 / bar hacks) 产生结果“src / foo src-1.0 / bar hacks”。 - Miguel

9
我认为您需要一些模式规则。试试这个。

我认为你想要一些模式规则。试试这个。

TARGETS = $(GRAPHDIR)/Complex.png \  
          $(GRAPHDIR)/Simple.png \ 
          $(GRAPHDIR)/IFileReader.png \
          $(GRAPHDIR)/McCabe-linear.png

%.png : %.dot
        dot $^ -Tpng -o $@

graphs: $(TARGETS)

4
更易于管理的内容:NAMES:=复杂的 简单的 IFileReader McCabe-linear,然后 TARGETS:=$(NAMES:%=$(GRAPHDIR)\%.png) - underscore_d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接