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