我有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
,需要“全部”。停止。
知道如何实现这一目标吗?
答案 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 Analysis
和8.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)