GNU Makefile - 具有一个依赖项的多个目标的模式规则忽略所有目标,但第一个
Posted
技术标签:
【中文标题】GNU Makefile - 具有一个依赖项的多个目标的模式规则忽略所有目标,但第一个【英文标题】:GNU Makefile - Pattern rule with multiple targets with one dependency ignores all targets but the first 【发布时间】:2015-01-08 08:58:21 【问题描述】:我想创建一个语言依赖目标。特别是:我有一个源文件,我想创建不同的对象,这些对象添加到相应的语言文件夹中。那个单一的源文件在 C 标志中会有所不同,编译器会得到。只要我以静态方式使用它,它就可以很好地工作。
de/info.o en/info.o es/info.o : info.c
$(ECHO) (DEP) $< for $@
现在我想,如果它更动态一点会很棒,以防我添加新的语言依赖文件。所以我使用了如下通配符:
de/%.o en/%.o es/%.o : %.c
$(ECHO) (DEP) $< for $@
但现在它只制作第一个目标而忽略其余的。 Make-Debug 打印以下内容:
Successfully remade target file `de/info.o'.
Considering target file `en/info.o'.
File `en/info.o' was considered already.
以防万一:不,对象不存在。所以没有目标,只有一个存在的依赖,所以 make 应该执行规则。
编辑:找到该问题的解决方案。
define FOO
$(1)/%.o : %.c
$(ECHO) $$< for $(1)
endef
$(foreach lang,$(LANGUAGE_LIST), $(eval $(call FOO,$(lang))))
灵感来自:http://www.gnu.org/software/make/manual/make.html#Eval-Function
【问题讨论】:
【参考方案1】:模式规则的工作方式与隐式规则不同。而隐含的规则,例如
a b c: d
command
等价于更长的符号
a: d
command
b: d
command
c: d
command
这不适用于模式规则。明确要求具有多个目标的模式规则在一次 command
调用中构建所有的目标。因此你必须写
$ cat GNUmakefile
all: de/x.o en/x.o es/x.o
de/%.o: %.c
@echo $@ from $<
en/%.o: %.c
@echo $@ from $<
es/%.o: %.c
@echo $@ from $<
$ gmake
de/x.o from x.c
en/x.o from x.c
es/x.o from x.c
相关文档见 GNU make 手册的10.5.1 Introduction to Pattern Rules:
模式规则可能有多个目标。与普通规则不同,这不会像许多具有相同先决条件和配方的不同规则一样起作用。如果模式规则有多个目标,make 知道规则的配方负责生成所有目标。该配方仅执行一次以生成所有目标。在搜索与目标匹配的模式规则时,与需要规则的目标匹配的规则之外的规则的目标模式是偶然的:只需担心为当前有问题的文件提供配方和先决条件。但是,当此文件的配方运行时,其他目标被标记为已自行更新。
【讨论】:
啊好吧,是的,我读到了这个……但我认为这个问题会有一个可靠的解决方案。因为每次添加语言时都必须添加目标。 好吧,如果您的命令是多行的,请考虑定义一个名为commands
的多行宏并将其与@$(call commands)
一起使用。那么每种新语言只需要添加两行。
宏是一个很好的提示! $(foreach , , )
、$(eval )
和 $(call)
的组合解决了这个问题!我编辑了我的第一篇文章。以上是关于GNU Makefile - 具有一个依赖项的多个目标的模式规则忽略所有目标,但第一个的主要内容,如果未能解决你的问题,请参考以下文章
具有多个依赖项的 taskjuggler,其中任务长度取决于先前的任务
配置具有公共依赖项的 TypeScript 项目以构建多个纯 JavaScript 输出文件