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