diff options
Diffstat (limited to 'app-shells/bash/files/bash-4.2-parallel-build.patch')
-rw-r--r-- | app-shells/bash/files/bash-4.2-parallel-build.patch | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/app-shells/bash/files/bash-4.2-parallel-build.patch b/app-shells/bash/files/bash-4.2-parallel-build.patch new file mode 100644 index 000000000000..ab2de86206a3 --- /dev/null +++ b/app-shells/bash/files/bash-4.2-parallel-build.patch @@ -0,0 +1,106 @@ +https://lists.gnu.org/archive/html/bug-bash/2011-10/msg00036.html + +the current yacc rules allow multiple runs to generate the same files. usually +this doesn't come up as the generated files are shipped in the tarball, but +when you modify parse.y (applying a patch or developing or whatever), you can +hit this problem. + +simple way of showing this: + make -j y.tab.{c,h} +a correct system would not show the yacc parser running twice :) + +simple patch is to have the .h file depend on the .c file, and have the .h file +itself issue a dummy rule (to avoid make thinking things changed). + +--- a/Makefile.in ++++ b/Makefile.in +@@ -579,16 +579,17 @@ + + # old rules + GRAM_H = parser-built +-y.tab.o: y.tab.c ${GRAM_H} command.h ${BASHINCDIR}/stdc.h input.h ++y.tab.o: y.tab.h y.tab.c ${GRAM_H} command.h ${BASHINCDIR}/stdc.h input.h + ${GRAM_H}: y.tab.h + @-if test -f y.tab.h ; then \ + cmp -s $@ y.tab.h 2>/dev/null || cp -p y.tab.h $@; \ + fi +-y.tab.c y.tab.h: parse.y ++y.tab.c: parse.y + # -if test -f y.tab.h; then mv -f y.tab.h old-y.tab.h; fi + $(YACC) -d $(srcdir)/parse.y + touch parser-built + # -if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; else cp -p y.tab.h ${GRAM_H}; fi ++y.tab.h: y.tab.c ; @true + + # experimental new rules - work with GNU make but not BSD (or OSF) make + #y.tab.o: y.tab.c y.tab.h + +https://lists.gnu.org/archive/html/bug-bash/2011-10/msg00037.html + +the current code generates a bunch of local libraries in subdirs and then +links bash against that. those subdirs sometimes need version.h. so they +have a rule to change back up to the parent dir and build version.h (which is +fine). the trouble is that the top level objects and the subdirs are allowed +to build in parallel, so it's possible for multiple children to see that +version.h is not available and that it needs to be created, so they all do. + +there is even more trouble is that version.h depends on all the top level +sources, some of which are compiled (like syntax.c). so these parallel +children all kick off a job to generate syntax.c which in turn requires the +mksyntax helper executable. obviously multiple processes rm-ing, compiling, +and linking the same files quickly falls apart. + +so tweak the subdirs to all depend on the .build target which in turn depends +on all of these top level files being generated. now the subdirs won't try and +recursively enter the top level. + +(noticed by David James) + +--- a/Makefile.in ++++ b/Makefile.in +@@ -597,6 +598,11 @@ + # $(YACC) -d $(srcdir)/parse.y + # -if cmp -s old-y.tab.h y.tab.h; then mv old-y.tab.h y.tab.h; fi + ++# Subdirs will often times want version.h, so they'll change back up to ++# the top level and try to create it. This causes parallel build issues ++# so just force top level sanity before we descend. ++$(LIBDEP): .build ++ + $(READLINE_LIBRARY): config.h $(READLINE_SOURCE) + @echo making $@ in ${RL_LIBDIR} + @( { test "${RL_LIBDIR}" = "${libdir}" && exit 0; } || \ + +http://lists.gnu.org/archive/html/bug-bash/2011-10/msg00107.html + +the top level Makefile will recurse into the defdir for multiple targets +(libbuiltins.a, common.o, bashgetopt.o, builtext.h), and since these do +not have any declared interdependencies, parallel makes will recurse into +the subdir and build the respective targets. + +nothing depends on common.o or bashgetopt.o, so those targets don't get +used normally. this leaves libbuiltins.a and builtext.h. at a glance, +this shouldn't be a big deal, but when we look closer, there's a subtle +failure lurking. + +most of the objects in the defdir need to be generated which means they +need to build+link the local mkbuiltins helper. the builtext.h header +also needs to be generated by the mkbuiltins helper. so when the top +level launches a child for libbuiltins.a and a child for builtext.h, we +can hit a race condition where the two try to generate mkbuiltins, and +the build randomly fails. + +so update libbuiltins.a to depend on builtext.h. this should be fairly +simple since it's only a single target. + +--- a/Makefile.in ++++ b/Makefile.in +@@ -674,7 +674,7 @@ + $(RM) $@ + ./mksyntax$(EXEEXT) -o $@ + +-$(BUILTINS_LIBRARY): $(BUILTIN_DEFS) $(BUILTIN_C_SRC) config.h ${BASHINCDIR}/memalloc.h version.h ++$(BUILTINS_LIBRARY): $(BUILTIN_DEFS) $(BUILTIN_C_SRC) config.h ${BASHINCDIR}/memalloc.h ${DEFDIR}/builtext.h version.h + @(cd $(DEFDIR) && $(MAKE) $(MFLAGS) DEBUG=${DEBUG} libbuiltins.a ) || exit 1 + + # these require special rules to circumvent make builtin rules |