如何通过一条规则解决依赖列表中的多个目标?
How to address multiple targets from dependency list by one rule?
我有以下 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: *** No rule to make target %.gz
, needed by `all'. Stop.
知道如何实现吗?
您想制作一些文件并压缩它们。不管怎样,你有
告诉 make
它们是什么,或者如何算出它们。
模式规则无法做到这一点。一个规则是一个模式规则当且仅当存在
在它的 target 一侧正好是一个 %
。参见 10.5 Defining and Redefining Pattern Rules。所以
%.o: %.c
$(CC) -c -o $@ $<
是模式规则,
也是
%.xyz: foobar
cp -f $< $@
他们告诉你,如果某个目标匹配左侧 %-wise,part 匹配 %
,那么该目标
具有将整个右侧的 %
替换为 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
s 内置资源的文档。
一旦您为 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)
我有以下 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: *** No rule to make target
%.gz
, needed by `all'. Stop.
知道如何实现吗?
您想制作一些文件并压缩它们。不管怎样,你有
告诉 make
它们是什么,或者如何算出它们。
模式规则无法做到这一点。一个规则是一个模式规则当且仅当存在
在它的 target 一侧正好是一个 %
。参见 10.5 Defining and Redefining Pattern Rules。所以
%.o: %.c
$(CC) -c -o $@ $<
是模式规则,
也是%.xyz: foobar
cp -f $< $@
他们告诉你,如果某个目标匹配左侧 %-wise,part 匹配 %
,那么该目标
具有将整个右侧的 %
替换为 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
s 内置资源的文档。
一旦您为 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)