2
votes

According to Gnu Make Manual and GNU Makefile - Pattern rule with multiple targets with one dependency ignores all targets but the first, pattern rule with multiple targets behaves different from normal rule. Latter is equivalent to multiple rules each with only one target.

Because I am designing a tool like make, I want to know the rationale behind this different behavior, why wouldn't both kinds of rules use the same logic?

EDIT:

For example, I have a Makefile:

%.md %.ps: %.tex
    echo "rule 1"

doc1.tar.gz: doc1.md doc1.ps
    echo "rule 2"

doc2.md doc2.ps: doc2.tex
    echo "rule 3"

doc2.tar.gz: doc2.md doc2.ps
    echo "rule 4"

make doc1.tar.gz gives me:

echo "rule 1"
rule 1
echo "rule 2"
rule 2

but doc2.tar.gz gives me:

echo "rule 3"
rule 3
echo "rule 3"
rule 3
echo "rule 4"
rule 4

My question is: Why rule 1 could not runs twice just like rule 3? What will be the problem if such pattern rule runs more than once?

1

1 Answers

1
votes

Imagine you have the following:

%.o: %.c
     $(CC) $(CFLAGS) -c $< -o $@

%.o: %.xx
     $(XX) $@ $<

The first rule tells make how to build a .o file if a .c file exists. The next rule tells it how to build a .o file if a .xx file exists. Because there's multiple ways to generate .o files, make will try to find a rule that matches (one where the dependencies are all accounted for).

Now consider:

foo.o : foo.dep

foo.o : foo.c
     $(CC) $(CFLAGS) -c $< -o $@

In this case, foo.o is a specific target, and you want make to run a specific rule. The author of the makefile is assumed to know ahead of time where this comes from, and therefore the author can write the correct rule. Notice that in this case, there's an extra dependency foo.o : foo.dep. This tells make, that if foo.d is out of date, it should rebuild foo.o. This sort of thing doesn't make sense for pattern rules, where you can have multiple rules generating the same file (because then, which rule(s) does the extra dependency apply to?). Not sure if that clarifies things.

BTW -- why reinvent the wheel -- why would you want to design a tool like make, and not just use make?