|
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 $< |
[Prev in Thread] | Current Thread | [Next in Thread] |