GNU Makefile - 具有一个依赖项的多个目标的模式规则忽略所有目标,但第一个

GNU Makefile - Pattern rule with multiple targets with one dependency ignores all targets but the first

我想制作一个语言依赖目标。特别是:我有一个源文件,我想创建不同的对象,将其添加到相应的语言文件夹中。该单个源文件的 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

模式规则与隐式规则的工作方式不同。而隐式规则如

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模式规则介绍

Pattern rules may have more than one target. Unlike normal rules, this does not act as many different rules with the same prerequisites and recipe. If a pattern rule has multiple targets, make knows that the rule’s recipe is responsible for making all of the targets. The recipe is executed only once to make all the targets. When searching for a pattern rule to match a target, the target patterns of a rule other than the one that matches the target in need of a rule are incidental: make worries only about giving a recipe and prerequisites to the file presently in question. However, when this file’s recipe is run, the other targets are marked as having been updated themselves.