bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bug: documentation suggests incorrect behavior (was: Bug: concurrent mak


From: Shachar Shemesh
Subject: Bug: documentation suggests incorrect behavior (was: Bug: concurrent make and references to different names of a multi-target rule)
Date: Sat, 09 Jun 2012 15:57:48 +0300
User-agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:13.0) Gecko/20120601 Thunderbird/13.0

I'm sorry for bringing up this relatively old thread.

<recap>
I claimed that a rule with two targets gets incorrectly processed by make when doing concurrent builds, as the two targets get built concurrently. Eli pointed out that I was mis-reading into what the rules were actually saying, and, as a result, was reporting as bug a documented behavior.
</recap>

At the time I wanted to reply, but failed to find my sources. Today I happened to stumble on them. The misleading behavior, i.e. - building two targets with one receipt invocation, is suggested by the documentation itself (which is where I originally got it too):

http://www.gnu.org/software/make/manual/make.html#Automatic-Prerequisites

We see a suggestion to generate the dependency file as part of the normal build, and then use sed to turn that into a multi-target rule. The code, as placed in the documentation, exhibits the same bug as my original question. Since I was relying on that code (from memory) when I wrote my incorrect make file, I would like to suggest that this be considered a bug in the documentation, and that an example be placed that produces better make scripts.

Original thread follows. Please delete before replying.

Thanks,
Shachar

On 02/19/2012 06:39 PM, Eli Zaretskii wrote:
Date: Sun, 19 Feb 2012 09:57:03 +0200
From: Shachar Shemesh <address@hidden>

To see the bug: run "make clean" and "make". /tmp/runlog shows one line
saying "run", which means that the t1 t2 rule was only invoked once. Now
run make clean and "make -j10". The /tmp/runlog now has two lines, showing
that the rule was invoked twice.

Make -d reveals that the rule was considered twice. Once as "t1", and
another time, before the first one had a chance to complete, as "t2". Make
does not realize that t1 and t2 are built by the same rule, and schedules
the receipt a second time.
Make cannot possibly realize that the same rule builds both t1 and t2,
because that's not what your rule says.  It says that _either_ one of
them is built by invoking the recipe in that rule.  So it invokes the
rule twice, one each for each one of them.

In sequential execution, once the rule was invoked for the first of
the two targets, the second already exists, so Make makes a shortcut
by not building it.  By contrast, in parallel execution, none of the
two exist, so Make tries to build them both in parallel, and ends up
invoking the same commands twice.

If you really want to tell Make that both targets are made by the same
rule, the only method you have is to use pattern rules, as
explained in this excerpt from the 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.  

An example is given later in the manual:

   This pattern rule has two targets:

     %.tab.c %.tab.h: %.y
             bison -d $<



reply via email to

[Prev in Thread] Current Thread [Next in Thread]