【问题标题】:Wildcard targets in a MakefileMakefile 中的通配符目标
【发布时间】:2010-12-10 15:36:36
【问题描述】:

如何压缩以下 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

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

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

    $(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)
    

    【讨论】:

    • @ Beta ,嗯,不知道。我通常处理处理特定于目录的情况,所以我只是习惯了它。 :)
    • 在“or just”之前添加了“Advanced stuff”(“or just”部分没有重复,我真的很难找到)。
    • @ShreevatsaR 好的,我已经对帖子进行了一些编辑:-)哇,我记得你,几年前我们在这里讨论算法。这些天你在忙什么? =)
    • 哈哈是的,我也记得你的名字;是的,在 Stack Overflow 的早期,这里有更多的算法问题,而且速度实际上可以跟上,我也是学生或刚毕业,有更多的时间和兴趣。现在我不知道我在做什么了 :-) (正式来说我是一名软件工程师,但是……)希望你一切都好!
    【解决方案2】:

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

    TARGETS = $(GRAPHDIR)/Complex.png \  
              $(GRAPHDIR)/Simple.png \ 
              $(GRAPHDIR)/IFileReader.png \
              $(GRAPHDIR)/McCabe-linear.png
    
    %.png : %.dot
            dot $^ -Tpng -o $@
    
    graphs: $(TARGETS)
    

    【讨论】:

    • 更易于管理:NAMES:=Complex Simple IFileReader McCabe-linear 然后TARGETS:=$(NAMES:%=$(GRAPHDIR)\%.png
    【解决方案3】:

    以防万一您真的想为当前目录中的每个 .DOT 生成一个 .PNG:

    %.png : %.dot
        dot -Tpng -o $@ $<
    
    all: $(addsuffix .png, $(basename $(wildcard *.dot)))
    

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

    【讨论】:

    • 基名不会删除 GRAPHDIR?
    • No: from the docs: "$(basename names...) 提取名称中每个文件名的后缀以外的所有内容。如果文件名包含句点,则基本名称是开始于(和不包括)最后一个句点。忽略目录部分中的句点。如果没有句点,则 basename 是整个文件名。例如,$(basename src/foo.c src-1.0/bar hacks) 产生结果'src/foo src-1.0/bar hacks'。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-16
    • 1970-01-01
    • 2021-09-27
    • 2017-11-08
    相关资源
    最近更新 更多