如何通过一个规则从依赖列表中处理多个目标?

时间:2016-03-26 02:58:37

标签: syntax makefile wildcard

我有Makefile的以下示例:

all: foo1.gz foo2.gz bar1.gz bar2.gz
  @echo Done.

foo1.gz:
  touch foo1 && gzip foo1

foo2.gz:
  touch foo2 && gzip foo2

bar1.gz:
  touch bar1 && gzip bar1

bar2.gz:
  touch bar2 && gzip bar2

旨在创建和gzip某些文件。这对于少量文件来说不是问题,但是当您有数百个文件时,您不希望将每个文件指定为给定目标的依赖项。

所以我想通过只指定一个依赖项而不是每个文件来简化上面的语法。

因此我希望语法如下:

all: %.gz

应该匹配多个目标,但它不起作用,并且失败了:

  

make:***没有规则来制作目标%.gz,需要“全部”。停止。

知道如何实现这一目标吗?

1 个答案:

答案 0 :(得分:2)

你想制作一些文件并压缩它们。你有这样或那样的方式 告诉make他们是什么,或如何弄清楚他们是什么。

模式规则不能这样做。当且仅当存在时,规则才是模式规则 在目标方面只有一个%。见10.5 Defining and Redefining Pattern Rules。所以

%.o: %.c
    $(CC) -c -o $@ $<

是一种模式规则,

也是如此
%.xyz: foobar
    cp -f $< $@

他们告诉你,如果某个目标与左侧的百分比匹配,部分匹配%,那么该目标 具有在整个右侧用{em> part 替换%所产生的先决条件, 并且该目标的配方是模式规则中的配方。

他们告诉你任何事情 是一个目标,无论如何:

all: %.gz
根据定义,

不是模式规则。左边没有%,它只是一个平原 表示目标all的旧规则具有先决条件%.gz

从广义上讲,你有两种方法可以让make知道你想要的一些文件名列表 处理:

拼写出来,例如:

files = foo1 foo2 bar1 bar2 ...

或告诉make计算它们的某种方式,例如

files = $(wildcard ...) # `make` globbing
files = $(shell ....) # shell filter

参见8.2 Functions for String Substitution and Analysis8.3 Functions for File Names 用于计算make内置资源的文档,用于计算文件名列表(或更一般的字符串列表)。

一旦您为make选择了一种识别您想要创建和压缩的文件的方法, 然后您可以使用模式规则来节省代码,例如:

<强>生成文件

zips := foo1.gz foo2.gz bar1.gz bar2.gz

.PHONY: all clean

all: $(zips)
    @echo Done.

%.gz:
    touch $(basename $@) && gzip $(basename $@)

clean:
    rm -f $(zips)