Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 421203 - sys-apps/fbset-2.1 fails to parallel-build
Summary: sys-apps/fbset-2.1 fails to parallel-build
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: [OLD] Core system (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Michal Januszewski (RETIRED)
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-06-15 07:54 UTC by Maxim Kammerer
Modified: 2012-07-10 09:32 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Maxim Kammerer 2012-06-15 07:54:52 UTC
One example:

 * fbset-2.1.tar.gz RMD160 SHA1 SHA256 size ;-) ...                                                                [ ok ]
 * checking ebuild checksums ;-) ...                                                                               [ ok ]
 * checking miscfile checksums ;-) ...                                                                             [ ok ]
>>> Unpacking source...
>>> Unpacking fbset-2.1.tar.gz to /var/tmp/portage/sys-apps/fbset-2.1/work
>>> Source unpacked in /var/tmp/portage/sys-apps/fbset-2.1/work
>>> Compiling source in /var/tmp/portage/sys-apps/fbset-2.1/work/fbset-2.1 ...
make -j3 
i686-pc-linux-gnu-gcc -Wall -Os -march=pentium3 -mtune=core2 -mfpmath=sse -fomit-frame-pointer -pipe -I. -Os -march=pentium3 -mtune=core2 -mfpmath=sse -fomit-frame-pointer -pipe   -c -o fbset.o fbset.c
bison -d modes.y
flex modes.l
bison -d modes.y
i686-pc-linux-gnu-gcc -Wall -Os -march=pentium3 -mtune=core2 -mfpmath=sse -fomit-frame-pointer -pipe -I. -Os -march=pentium3 -mtune=core2 -mfpmath=sse -fomit-frame-pointer -pipe   -c -o modes.tab.o modes.tab.c
modes.tab.c:162:2: error: invalid preprocessing directive #l
modes.y:33:13: warning: ‘ClearVideoMode’ defined but not used
make: *** [modes.tab.o] Error 1
make: *** Waiting for unfinished jobs....
emake failed


In modes.tab.c, line 162 contains:

#line 163 "modes.tab.c"

So it's clear that gcc was reading the file while the second bison invocation didn't complete writing to it. Question is, why is bison invoked twice? Dependencies in Makefile seem correct. From reading GNU make manual, however (Rules -> Multiple Targets), it seems that something like

target1 target2: dep
  cmd

is actually equivalent to

target1: dep
  cmd

target2: dep
  cmd

So there are two paths for bison invocation:

modes.y -> modes.tab.c -> modes.tab.o -> fbset
modes.y -> modes.tab.h -> lex.yy.o -> fbset

In parallel build, bison can be invoked twice, separately for modes.tab.h and for modes.tab.c. I guess that the easiest solution for such a small package is enforcing -j1.
Comment 1 Jeroen Roovers (RETIRED) gentoo-dev 2012-06-15 14:15:13 UTC
It took 10 iterations, but yes, this is confirmed. :)
Comment 2 Maxim Kammerer 2012-06-15 14:58:45 UTC
Seems that multi-target *pattern* rules are still safe for parallel make:
http://www.gnu.org/software/make/manual/make.html#Pattern-Intro

Explains why similar bugs are not encountered that often.
Comment 3 Maxim Kammerer 2012-07-10 07:27:46 UTC
This seems easy to fix, no? Just filter out make -j*.
Comment 4 Diego Elio Pettenò (RETIRED) gentoo-dev 2012-07-10 08:40:39 UTC
No. That's not a fix, it's a workaround.
Comment 5 Diego Elio Pettenò (RETIRED) gentoo-dev 2012-07-10 08:42:58 UTC
FWIW http://goo.gl/PYRMk gives you an idea how this works and how it can be fixed (although that particular use of timestamps is overkill in this situation.
Comment 6 Diego Elio Pettenò (RETIRED) gentoo-dev 2012-07-10 08:51:26 UTC
Fixed, properly. Interestingly the extra failure was _added_ by Gentoo as the one before was actually much easier to spot (instead of a race condition you had a make failure for missing targets).

The correct fix is to add a dependency from the .h file to the .c one, as the two are generated together.
Comment 7 Maxim Kammerer 2012-07-10 09:10:44 UTC
(In reply to comment #6)
> The correct fix is to add a dependency from the .h file to the .c one, as
> the two are generated together.

That's not a correct fix, since bison is called twice (albeit without a race). The correct fix is to make a pattern rule:

%.tab.h %.tab.c:    %.y
        $(BISON) $<
Comment 8 Diego Elio Pettenò (RETIRED) gentoo-dev 2012-07-10 09:14:21 UTC
No your's wrong, mine's correct. Your's exactly like the one you had before; the multi-target pattern rules are parallel safe _between the rules themselves_, but they still cause multiple calls — you, like Mr Bones who "fixed" it before, are misreading the way make works with multiple output.

Given I have heavily-multicore machines, and years of experience with make, I think I can safely say I know what I'm doing.
Comment 9 Maxim Kammerer 2012-07-10 09:16:54 UTC
My mistake, I assumed that the previous multi-target rule was also left in place (wrote this before the change was in CVS). A multi-target pattern rule is still better, though.
Comment 10 Diego Elio Pettenò (RETIRED) gentoo-dev 2012-07-10 09:18:57 UTC
Your multi-target pattern rule is also _broken_, just the way it was before.

%.tab.h %.tab.c:    %.y
        $(BISON) $<

still means

%.tab.h    %.y
        $(BISON) $<

%.tab.h:    %.y
        $(BISON) $<

which causes bison to be called twice (with a race condition). Again, you didn't understand Makefile syntax, I know it's hard, but trust me I've been fixing this kind of stuff for the past few years.
Comment 11 Maxim Kammerer 2012-07-10 09:32:08 UTC
(In reply to comment #10)
> Your multi-target pattern rule is also _broken_, just the way it was before.
>
> [...]
> 
> which causes bison to be called twice (with a race condition). Again, you
> didn't understand Makefile syntax, I know it's hard, but trust me I've been
> fixing this kind of stuff for the past few years.

To be honest, your attempts at condescendence are annoying. I assure you that I know GNU Make better than you -- although I will not provide proof, since this username is a pseudonym, so feel free to think otherwise.

In any case, please refer to the link posted in comment #2:

"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."

This is easily verified by replacing the multi-target rule with a pattern rule provided above, and observing the lack of a race condition after repeated invocations of make -j<num>.

With that said, I appreciate your work, but please don't automatically assume that your expertise level is better than anyone else's just because you are familiar with a given subject.