# We need to build `emacs' in `src' to compile the *.elc files in `lisp'.
lisp: src
+# Pass to src/Makefile.in an additional BOOTSTRAPEMACS variable which
+# is either set to bootstrap-emacs (in case bootstrap-emacs has not been
+# constructed yet) or the empty string (otherwise).
+# src/Makefile.in uses it to implement conditional dependencies, so that
+# files that need bootstrap-emacs to be built do not additionally need
+# to be kept fresher than bootstrap-emacs. Otherwise changing a single
+# file src/foo.c forces dumping a new bootstrap-emacs, then re-byte-compiling
+# all preloaded elisp files, and only then dump the actual src/emacs, which
+# is not wrong, but is overkill in 99.99% of the cases.
${SUBDIR}: ${SUBDIR_MAKEFILES} FRC
- cd $@; $(MAKE) all $(MFLAGS) \
+ boot=bootstrap-emacs$(EXEEXT); \
+ if [ -x "src/$$boot" ]; then boot=""; fi; \
+ cd $@; $(MAKE) all $(MFLAGS) \
CC='${CC}' CFLAGS='${CFLAGS}' CPPFLAGS='${CPPFLAGS}' \
- LDFLAGS='${LDFLAGS}' MAKE='${MAKE}'
+ LDFLAGS='${LDFLAGS}' MAKE='${MAKE}' BOOTSTRAPEMACS="$$boot"
blessmail: ${SUBDIR_MAKEFILES} src FRC
cd lib-src; $(MAKE) maybe-blessmail $(MFLAGS) \
# Files to compile before others during a bootstrap. This is done to
# speed up the bootstrap process.
-# Why `subr.elc'? It's dumped so byte-compiling it early shouldn't make
-# any difference!? --Stef
-# Some CC files are compiled first because CC mode tweaks the compilation
-# process, and requiring cc-mode when it is not compiled doesn't work during
-# the bootstrapping.
COMPILE_FIRST = \
$(lisp)/emacs-lisp/bytecomp.elc \
$(lisp)/emacs-lisp/byte-opt.elc \
- $(lisp)/subr.elc \
- $(lisp)/progmodes/cc-mode.elc \
- $(lisp)/progmodes/cc-vars.elc
+ $(lisp)/emacs-lisp/autoload.elc
# The actual Emacs command run in the targets below.
echo Directories: $$wins; \
$(emacs) -l autoload --eval '(setq generated-autoload-file "$(lisp)/loaddefs.el")' -f batch-update-autoloads $$wins
-# This is required by the witness-emacs target in ../src/Makefile, so
+# This is required by the bootstrap-emacs target in ../src/Makefile, so
# we know that if we have an emacs executable, we also have a subdirs.el.
$(lisp)/subdirs.el:
$(MAKE) $(MFLAGS) update-subdirs
Files included conditionally here should be included (unconditionally)
in SOME_MACHINE_LISP. */
+/* Please loaddefs.el first, so it gets generated first, since it is on
+ the critical path (relevant in parallel compilations). */
+
lisp= \
+ ${lispsource}loaddefs.el \
${lispsource}abbrev.elc \
${lispsource}buff-menu.elc \
${lispsource}button.elc \
${lispsource}isearch.elc \
${lispsource}rfn-eshadow.elc \
${lispsource}loadup.el \
- ${lispsource}loaddefs.el \
${lispsource}bindings.elc \
${lispsource}emacs-lisp/map-ynp.elc \
${lispsource}menu-bar.elc \
It need not contain the files that are loaded conditionally
because SOME_MACHINE_LISP has those. */
shortlisp= \
+ ../lisp/loaddefs.el \
../lisp/abbrev.elc \
../lisp/buff-menu.elc \
../lisp/button.elc \
../lisp/isearch.elc \
../lisp/rfn-eshadow.elc \
../lisp/loadup.el \
- ../lisp/loaddefs.el \
../lisp/bindings.elc \
../lisp/emacs-lisp/map-ynp.elc \
../lisp/env.elc \
mostlyclean:
rm -f temacs${EXEEXT} prefix-args${EXEEXT} core *.core \#* *.o libXMenu11.a liblw.a
rm -f ../etc/DOC
- rm -f bootstrap-emacs${EXEEXT} emacs-${version}${EXEEXT} witness-emacs
+ rm -f bootstrap-emacs${EXEEXT} emacs-${version}${EXEEXT}
rm -f buildobj.lst
clean: mostlyclean
rm -f emacs-*.*.*${EXEEXT} emacs${EXEEXT}
To solve the circularity, we use 2 different Emacs executables,
"emacs" is the main target and "bootstrap-emacs" is the one used
to build the *.elc and loaddefs.el files.
- To solve the freshness issue, we use a third file "witness-emacs"
- which is used to witness the fact that there is a bootstrap-emacs
- executable. */
+ To solve the freshness issue, we used to use a third file "witness-emacs"
+ which was used to witness the fact that there is a bootstrap-emacs
+ executable, and then have dependencies on witness-emacs rather than
+ bootstrap-emacs, but that lead to problems in parallel builds (because
+ witness-emacs needed to be free from dependencies (to avoid rebuilding
+ it), so it was compiled in parallel, leading typically to having 2
+ processes dumping bootstrap-emacs at the same time).
+ So instead, we replace the witness-emacs dependencies by conditional
+ bootstrap-dependencies (via ${BOOTSTRAPEMACS}). Of course, since we do
+ not want to rely on GNU Make features, we have to rely on an external
+ script to do the conditional part of the dependency
+ (i.e. see the ${SUBDIR} rule ../Makefile.in). */
-/* These suffix rules do not allow additional dependencies, sadly, so
- adding a bootstrap-emacs%{EXEEXT} dependency does not work --Stef */
.SUFFIXES: .elc .el
+/* These suffix rules do not allow additional dependencies, sadly, so
+ instead of adding a $(BOOTSTRAPEMACS) dependency here, we add it
+ separately below.
+ With GNU Make, we would just say "%.el : %.elc $(BOOTSTRAPEMACS)" */
.el.elc:
@cd ../lisp; $(MAKE) $(MFLAGS) compile-onefile \
- THEFILE=$< EMACS=../src/bootstrap-emacs${EXEEXT}
+ THEFILE=$< EMACS=../src/bootstrap-emacs${EXEEXT}
-/* Since the .el.elc rule cannot specify an extra dependency, we do it here.
- The byte-compiler dependency is not necessary, but it substantially
- speeds up byte-compilation of the other files.
- Of course, it also has the downside of forcing a recompilation of all
- those files whenever a file in $PRECOMP changes. */
-${lisp} ${SOME_MACHINE_LISP}: witness-emacs
+/* Since the .el.elc rule cannot specify an extra dependency, we do it here. */
+${lisp} ${SOME_MACHINE_LISP}: $(BOOTSTRAPEMACS)
-../lisp/loaddefs.el: witness-emacs
+../lisp/loaddefs.el: $(BOOTSTRAPEMACS)
cd ../lisp; $(MAKE) $(MFLAGS) autoloads EMACS=../src/bootstrap-emacs${EXEEXT}
/* Dump an Emacs executable named bootstrap-emacs containing the
files from loadup.el in source form. */
bootstrap-emacs${EXEEXT}: temacs${EXEEXT}
+ cd ../lisp; $(MAKE) $(MFLAGS) update-subdirs
#ifdef CANNOT_DUMP
ln temacs${EXEEXT} bootstrap-emacs${EXEEXT}
#else
$(RUN_TEMACS) --batch --load loadup bootstrap
mv -f emacs${EXEEXT} bootstrap-emacs${EXEEXT}
#endif /* ! defined (CANNOT_DUMP) */
-
-witness-emacs: temacs${EXEEXT}
- cd ../lisp; $(MAKE) $(MFLAGS) update-subdirs
- $(MAKE) $(MFLAGS) bootstrap-emacs${EXEEXT}
- touch witness-emacs
@: Compile some files earlier to speed up further compilation.
cd ../lisp; $(MAKE) $(MFLAGS) compile-first EMACS=../src/bootstrap-emacs${EXEEXT}