Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I want to make a language depend target. In Particular: I have one source-file and I want to create different Objects which where add to the corresponding language folder. That single source file will differ in the C-Flags, the compiler will get. As long as I used it in a static way, it works quite fine.

de/info.o en/info.o es/info.o : info.c
    $(ECHO)     (DEP) $< for $@

Now I thought, it would be great if it is a bit more dynamic, in case i'll add a new language depending file. So I used a wildcard as followed:

de/%.o en/%.o es/%.o : %.c
    $(ECHO)     (DEP) $< for $@

But now it just make the first target and ignores the rest. The Make-Debug prints the following thing:

Successfully remade target file `de/info.o'.
Considering target file `en/info.o'.
File `en/info.o' was considered already.

Just in case: No, the objects do not exist. So there is no target, but an existing dependencie, so make should execute the rules.

EDIT: Found a solution for that Problem.

define FOO

$(1)/%.o : %.c
    $(ECHO)     $$< for $(1)

endef

 $(foreach lang,$(LANGUAGE_LIST), $(eval $(call FOO,$(lang))))

Inspired by: http://www.gnu.org/software/make/manual/make.html#Eval-Function

like image 848
Mario Avatar asked Jan 08 '15 08:01

Mario


1 Answers

Pattern rules work differently than implicit rules. While an implicit rule such as

a b c: d
      command

is equivalent to the longer notation

a: d
      command
b: d
      command
c: d
      command

this does NOT hold for pattern rules. Pattern rules with multiple targets are explicitly required to build all of their targets in a single invocation of command. Thus you would have to write

$ 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

The relevant documentation is found in 10.5.1 Introduction to Pattern Rules of the GNU make manual:

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.

like image 142
Jens Avatar answered Sep 18 '22 06:09

Jens