declare smobs in alloc.c
[bpt/emacs.git] / Makefile.in
index 969a224..0fd9f98 100644 (file)
@@ -1,6 +1,6 @@
 ### @configure_input@
 
-# Copyright (C) 1992-2013 Free Software Foundation, Inc.
+# Copyright (C) 1992-2014 Free Software Foundation, Inc.
 
 # This file is part of GNU Emacs.
 
@@ -48,6 +48,8 @@
 #
 # make extraclean
 #      Still more severe - delete backup and autosave files, too.
+#      Also generated files that do not normally change and can be slow
+#      to rebuild (eg leim/ja-dic).
 #
 # make bootstrap
 #      Removes all the compiled files to force a new bootstrap from a
@@ -58,8 +60,8 @@
 
 SHELL = @SHELL@
 
-# This may not work with certain non-GNU make's.  It only matters when
-# inheriting a CDPATH not starting with the current directory.
+# This only matters when inheriting a CDPATH not starting with the
+# current directory.
 CDPATH=
 
 # If Make doesn't predefine MAKE, set it here.
@@ -74,10 +76,11 @@ QUIET_SUBMAKE = MAKELEVEL=0
 cache_file = @cache_file@
 CONFIGURE_FLAGS = --cache-file=$(cache_file)
 
-CC=@CC@
-CFLAGS=@CFLAGS@
-LDFLAGS=@LDFLAGS@
-CPPFLAGS=@CPPFLAGS@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+ACLOCAL = @ACLOCAL@
+
 EXEEXT=@EXEEXT@
 
 ### These help us choose version- and architecture-specific directories
@@ -144,8 +147,7 @@ man1dir=$(mandir)/man1
 # Where to install and expect the info files describing Emacs.
 infodir=@infodir@
 # Info files not in the doc/misc directory (we get those via make echo-info).
-INFO_EXT=@INFO_EXT@
-INFO_NONMISC=emacs$(INFO_EXT) eintr$(INFO_EXT) elisp$(INFO_EXT)
+INFO_NONMISC=emacs.info eintr.info elisp.info
 
 # If no makeinfo was found and configured --without-makeinfo, "no"; else "yes".
 HAVE_MAKEINFO=@HAVE_MAKEINFO@
@@ -164,9 +166,6 @@ bitmapdir=@bitmapdir@
 # We use $(srcdir) explicitly in dependencies so as not to depend on VPATH.
 srcdir=@srcdir@
 abs_srcdir=@abs_srcdir@
-abs_builddir=@abs_builddir@
-# MinGW CPPFLAGS may use this.
-abs_top_srcdir=@abs_top_srcdir@
 
 # Where the manpage source files are kept.
 mansrcdir=$(srcdir)/doc/man
@@ -191,15 +190,13 @@ iconsrcdir=$(srcdir)/etc/images/icons
 # These variables hold the values Emacs will actually use.  They are
 # based on the values of the standard Make variables above.
 
-# Where to install the lisp, leim files distributed with
-# Emacs.  This includes the Emacs version, so that the
-# lisp files for different versions of Emacs will install
-# themselves in separate directories.
+# Where to install the lisp files distributed with Emacs.
+# This includes the Emacs version, so that the lisp files for different
+# versions of Emacs will install themselves in separate directories.
 lispdir=@lispdir@
-leimdir=@leimdir@
 
 # Directories Emacs should search for standard lisp files.
-# The default is ${lispdir}:${leimdir}.
+# The default is ${lispdir}.
 standardlisppath=@standardlisppath@
 
 # Directories Emacs should search for lisp files specific to this
@@ -219,11 +216,9 @@ lisppath=@lisppath@
 # to help Emacs find its lisp files before they've been installed
 # in their final location.
 # This should be a colon-separated list of directories.
-# Normally it points to the lisp/ directory in the sources and
-# the leim/ directory in the build tree.
+# Normally it points to the lisp/ directory in the sources.
 # NB lread.c relies on lisp/ being first here.
-# TODO generate leim in srcdir also, prebuild in tarfiles.
-buildlisppath=${abs_srcdir}/lisp:${abs_builddir}/leim
+buildlisppath=${abs_srcdir}/lisp
 
 # Where to install the other architecture-independent
 # data files distributed with Emacs (like the tutorial,
@@ -278,7 +273,7 @@ EMACS = ${EMACS_NAME}${EXEEXT}
 EMACSFULL = `echo emacs-${version} | sed '$(TRANSFORM)'`${EXEEXT}
 
 # Subdirectories to make recursively.
-SUBDIR = $(NTDIR) lib lib-src src lisp leim
+SUBDIR = $(NTDIR) lib lib-src src lisp
 
 # The subdir makefiles created by config.status.
 SUBDIR_MAKEFILES_IN = @SUBDIR_MAKEFILES_IN@
@@ -287,14 +282,13 @@ SUBDIR_MAKEFILES = `echo $(SUBDIR_MAKEFILES_IN:.in=) | sed 's|$(srcdir)/||g'`
 # Subdirectories to install, and where they'll go.  lib-src's and nt's
 # makefiles know how to install them, so we don't do that here.
 # Directories that cannot simply be copied, eg info, are treated
-# separately.  quail appears twice because in out-of-tree builds, it
-# exists twice.
-COPYDIR = ${srcdir}/etc ${srcdir}/lisp ${srcdir}/leim/ja-dic ${srcdir}/leim/quail leim/quail
-COPYDESTS = "$(DESTDIR)${etcdir}" "$(DESTDIR)${lispdir}" "$(DESTDIR)${leimdir}/ja-dic" "$(DESTDIR)${leimdir}/quail" "$(DESTDIR)${leimdir}/quail"
+# separately.
+COPYDIR = ${srcdir}/etc ${srcdir}/lisp
+COPYDESTS = "$(DESTDIR)${etcdir}" "$(DESTDIR)${lispdir}"
 
-all: ${SUBDIR}
+all: ${SUBDIR} info
 
-.PHONY: all ${SUBDIR} blessmail epaths-force epaths-force-w32 FRC
+.PHONY: all ${SUBDIR} blessmail epaths-force epaths-force-w32
 
 removenullpaths=sed -e 's/^:*//' -e 's/:*$$//g' -e 's/::*/:/g'
 
@@ -302,7 +296,15 @@ removenullpaths=sed -e 's/^:*//' -e 's/:*$$//g' -e 's/::*/:/g'
 # See comments in configure.ac for why it is done this way, as opposed
 # to just letting configure generate epaths.h from epaths.in in a
 # similar way to how Makefile is made from Makefile.in.
-epaths-force: FRC
+epaths-force:
+       @for dir in '$(abs_srcdir)' '$(lispdir)' '$(archlibdir)'; do \
+         case $$dir in \
+           *:*) \
+             echo >&2 "Build or installation directory '$$dir'"; \
+             echo >&2 "cannot contain ':'."; \
+             exit 1;; \
+         esac; \
+       done
        @(standardlisppath=`echo "${standardlisppath}" | ${removenullpaths}` ; \
          locallisppath=`echo "${locallisppath}" | ${removenullpaths}` ; \
          buildlisppath=`echo "${buildlisppath}" | ${removenullpaths}` ; \
@@ -339,17 +341,15 @@ msys_sed_sh_escape=sed -e 's/[];$$*.^[]/\\\\&/g'
 # MS-Windows format (e.g. 'c:/foo/bar'), because temacs is a MinGW
 # program that doesn't support MSYS-style paths (e.g. '/c/foo/bar' or
 # '/foo/bar').
-epaths-force-w32: FRC
+epaths-force-w32:
        @(w32srcdir=`${srcdir}/build-aux/msys-to-w32 "${srcdir}"`; \
-         w32blddir=`${srcdir}/build-aux/msys-to-w32 .`; \
          w32prefix=`${srcdir}/build-aux/msys-to-w32 "${prefix}" N`; \
-         w32prefixpattern=`echo "${w32prefix}" | ${msys_sed_sh_escape}` ; \
+         w32prefixpattern=`echo "$${w32prefix}" | ${msys_sed_sh_escape}` ; \
          w32locallisppath=`${srcdir}/build-aux/msys-to-w32 "${locallisppath}" N ":" "\\;" | ${msys_w32prefix_subst}` ; \
          sed < ${srcdir}/nt/epaths.nt > epaths.h.$$$$          \
          -e 's;\(#.*PATH_SITELOADSEARCH\).*$$;\1 "'"$${w32locallisppath}"'";' \
          -e '/^.*#/s/@VER@/${version}/g'                       \
          -e '/^.*#/s/@CFG@/${configuration}/g'                 \
-         -e '/^.*#/s|@BLD@|$${w32blddir}|g'                    \
          -e "/^.*#/s|@SRC@|$${w32srcdir}|g") &&                \
        ${srcdir}/build-aux/move-if-change epaths.h.$$$$ src/epaths.h
 
@@ -361,40 +361,25 @@ lib-src src: $(NTDIR) lib
 
 src: lib-src
 
-# We need to build `emacs' in `src' to compile the *.elc files in `lisp'
-# and `leim'.
-lisp leim: src
+# We need to build `emacs' in `src' to compile the *.elc files in `lisp'.
+lisp: src
 
 # These targets should be "${SUBDIR} without `src'".
-lib lib-src lisp leim nt: Makefile FRC
-       cd $@ && $(MAKE) all $(MFLAGS)                         \
-         CC='${CC}' CFLAGS='${CFLAGS}' CPPFLAGS='${CPPFLAGS}' \
-         LDFLAGS='${LDFLAGS}' MAKE='${MAKE}'
-
-# 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.
-src: Makefile FRC
+lib lib-src lisp nt: Makefile
+       $(MAKE) -C $@ all
+
+# Note the use of single quotes in the value of vcswitness.
+# This passes an unexpanded $srcdir to src's Makefile, which then
+# expands it using its own value of srcdir (which points to the
+# source directory of src/).
+src: Makefile
        dirstate='.bzr/checkout/dirstate';                              \
        vcswitness='$$(srcdir)/../'$$dirstate;                          \
        [ -r "$(srcdir)/$$dirstate" ] || vcswitness='';                 \
-       cd $@ || exit;                                                  \
-       boot=bootstrap-emacs$(EXEEXT);                                  \
-       [ ! -x "$$boot" ] || boot='';                                   \
-       $(MAKE) all $(MFLAGS)                                           \
-         CC='${CC}' CFLAGS='${CFLAGS}' CPPFLAGS='${CPPFLAGS}'          \
-         LDFLAGS='${LDFLAGS}' MAKE='${MAKE}' BOOTSTRAPEMACS="$$boot"   \
-         VCSWITNESS="$$vcswitness"
-
-blessmail: Makefile src FRC
-       cd lib-src && $(MAKE) maybe-blessmail $(MFLAGS) \
-         MAKE='${MAKE}' archlibdir='$(archlibdir)'
+       $(MAKE) -C $@ all VCSWITNESS="$$vcswitness"
+
+blessmail: Makefile src
+       $(MAKE) -C lib-src maybe-blessmail
 
 # We used to have one rule per */Makefile.in, but that leads to race
 # conditions with parallel makes, so let's assume that the time stamp on
@@ -425,16 +410,17 @@ config.status: ${srcdir}/configure ${srcdir}/lisp/version.el
 AUTOCONF_INPUTS = $(srcdir)/configure.ac $(srcdir)/aclocal.m4
 
 $(srcdir)/configure: $(AUTOCONF_INPUTS)
-       cd ${srcdir} && autoconf
+       cd ${srcdir} && ${AUTOCONF}
 
+ACLOCAL_PATH = @ACLOCAL_PATH@
 ACLOCAL_INPUTS = $(srcdir)/configure.ac $(srcdir)/m4/gnulib-comp.m4
 $(srcdir)/aclocal.m4: $(ACLOCAL_INPUTS)
-       cd $(srcdir) && aclocal -I m4
+       cd $(srcdir) && ACLOCAL_PATH='$(ACLOCAL_PATH)' $(ACLOCAL) -I m4
 
 AUTOMAKE_INPUTS = $(srcdir)/aclocal.m4 $(srcdir)/lib/Makefile.am \
   $(srcdir)/lib/gnulib.mk
 $(srcdir)/lib/Makefile.in: $(AUTOMAKE_INPUTS)
-       cd $(srcdir) && automake --gnu -a -c lib/Makefile
+       cd $(srcdir) && $(AUTOMAKE) --gnu -a -c lib/Makefile
 
 # Regenerate files that this makefile would have made, if this makefile
 # had been built by Automake.  The name 'am--refresh' is for
@@ -447,9 +433,9 @@ $(srcdir)/src/config.in: $(srcdir)/src/stamp-h.in
        @ # because stamp-h.in has changed (since building stamp-h.in
        @ # refreshes config.in as well), but if config.in is missing
        @ # then we really need to do something more.
-       [ -r "$@" ] || ( cd ${srcdir} && autoheader )
+       [ -r "$@" ] || ( cd ${srcdir} && ${AUTOHEADER} )
 $(srcdir)/src/stamp-h.in: $(AUTOCONF_INPUTS)
-       cd ${srcdir} && autoheader
+       cd ${srcdir} && ${AUTOHEADER}
        rm -f $(srcdir)/src/stamp-h.in
        echo timestamp > $(srcdir)/src/stamp-h.in
 
@@ -486,11 +472,7 @@ write_subdir=if [ -f "$${subdir}/subdirs.el" ]; \
 ### Lisp files and DOC file to work properly.
 install-arch-dep: src install-arch-indep install-etcdoc install-$(NTDIR)
        umask 022; ${MKDIR_P} "$(DESTDIR)${bindir}"
-       cd lib-src && \
-         $(MAKE) install $(MFLAGS) prefix="${prefix}" \
-           exec_prefix="${exec_prefix}" bindir="${bindir}" \
-           libexecdir="${libexecdir}" archlibdir="${archlibdir}" \
-           INSTALL_STRIP=${INSTALL_STRIP}
+       $(MAKE) -C lib-src install
        if test "${ns_self_contained}" = "no"; then \
          ${INSTALL_PROGRAM} $(INSTALL_STRIP) src/emacs${EXEEXT} "$(DESTDIR)${bindir}/$(EMACSFULL)" || exit 1 ; \
          chmod 1755 "$(DESTDIR)${bindir}/$(EMACSFULL)" || true; \
@@ -508,11 +490,7 @@ install-arch-dep: src install-arch-indep install-etcdoc install-$(NTDIR)
 ### in nt/, and its Posix do-nothing shadow.
 install-:
 install-nt:
-       cd $(NTDIR) && \
-         $(MAKE) install $(MFLAGS) prefix="${prefix}" \
-           exec_prefix="${exec_prefix}" bindir="${bindir}" \
-           libexecdir="${libexecdir}" archlibdir="${archlibdir}" \
-           INSTALL_STRIP=${INSTALL_STRIP}
+       $(MAKE) -C $(NTDIR) install
 
 ## In the share directory, we are deleting:
 ## applications (with emacs.desktop, also found in etc/)
@@ -567,7 +545,7 @@ set_installuser=for installuser in $${LOGNAME} $${USERNAME} $${USER} \
 ## work correctly, and therefore no idea when tar can be replaced.
 ## See also these comments from 2004 about cp -r working fine:
 ## http://lists.gnu.org/archive/html/autoconf-patches/2004-11/msg00005.html
-install-arch-indep: lisp leim install-info install-man ${INSTALL_ARCH_INDEP_EXTRA}
+install-arch-indep: lisp install-info install-man ${INSTALL_ARCH_INDEP_EXTRA}
        -set ${COPYDESTS} ; \
        unset CDPATH; \
        $(set_installuser); \
@@ -579,13 +557,8 @@ install-arch-indep: lisp leim install-info install-man ${INSTALL_ARCH_INDEP_EXTR
            [ "$$exp_dest" = "`cd $${dir} && /bin/pwd`" ] && continue ; \
          else true; \
          fi; \
-         if [ "$${dir}" = "leim/quail" ]; then \
-           [ "`cd $${dir} && /bin/pwd`" = "`cd ${srcdir}/leim/quail && /bin/pwd`" ] && \
-             continue ; \
-         else \
-           rm -rf "$${dest}" ; \
-           umask 022; ${MKDIR_P} "$${dest}" ; \
-         fi ; \
+         rm -rf "$${dest}" ; \
+         umask 022; ${MKDIR_P} "$${dest}" ; \
          echo "Copying $${dir} to $${dest}..." ; \
          (cd $${dir}; tar -chf - . ) \
            | (cd "$${dest}"; umask 022; \
@@ -612,26 +585,18 @@ install-arch-indep: lisp leim install-info install-man ${INSTALL_ARCH_INDEP_EXTR
            done ); \
          find "$${dest}" -exec chown $${installuser} {} ';' ;\
        done
-       -rm -f "$(DESTDIR)${leimdir}/leim-list.el"
-       ${INSTALL_DATA} leim/leim-list.el "$(DESTDIR)${leimdir}/leim-list.el"
        -rm -f "$(DESTDIR)${lispdir}/subdirs.el"
        umask 022; $(srcdir)/build-aux/update-subdirs "$(DESTDIR)${lispdir}"
        subdir="$(DESTDIR)${datadir}/emacs/${version}/site-lisp" ; \
          ${write_subdir}
        subdir="$(DESTDIR)${datadir}/emacs/site-lisp" ; \
          ${write_subdir} || true
-       [ -z "${GZIP_PROG}" ] || \
-         ( echo "Compressing *.el ..." ; \
-           unset CDPATH; \
-           thisdir=`/bin/pwd`; \
-           for dir in "$(DESTDIR)${lispdir}" "$(DESTDIR)${leimdir}"; do \
-             cd "$${thisdir}" ; \
-             cd "$${dir}" || exit 1 ; \
-             for f in `find . -name "*.elc" -print`; do \
-               f_el=`echo "$$f" | sed 's/.elc$$/.el/'`; \
-               ${GZIP_PROG} -9n "$$f_el" ; \
-             done ; \
-           done )
+       [ -z "${GZIP_PROG}" ] || { \
+         echo "Compressing *.el ..." && \
+         cd "$(DESTDIR)${lispdir}" && \
+         find . -name '*.elc' -exec $(SHELL) -c \
+           '${GZIP_PROG} -9n `expr "$$1" : "\\(.*\\)c"`' dummy '{}' ';'; \
+       }
        -chmod -R a+r "$(DESTDIR)${datadir}/emacs/${version}" ${COPYDESTS}
 
 ## The above chmods are needed because "umask 022; tar ..." is not
@@ -653,6 +618,13 @@ install-etcdoc: src install-arch-indep
             chown $${installuser} "$(DESTDIR)${etcdocdir}/$${docfile}" || true ; \
        else true; fi
 
+## FIXME:
+## If info/dir is missing, but we have install-info, we should let
+## that handle it.  If info/dir is present and we do not have install-info,
+## we should check for missing entries and add them by hand.
+##
+## FIXME:
+## If HAVE_MAKEINFO = no and there are no info files, do not install info/dir.
 install-info: info
        umask 022; ${MKDIR_P} "$(DESTDIR)${infodir}"
        -unset CDPATH; \
@@ -661,11 +633,10 @@ install-info: info
        if [ "`cd ${srcdir}/info && /bin/pwd`" = "$$exp_infodir" ]; then \
          true; \
        else \
-         (cd "$(DESTDIR)${infodir}"; \
-          [ -f dir ] || \
-            (cd "$${thisdir}"; \
-             ${INSTALL_DATA} ${srcdir}/info/dir "$(DESTDIR)${infodir}/dir") ); \
-          info_misc=`cd doc/misc && $(QUIET_SUBMAKE) $(MAKE) -s echo-info`; \
+          [ -f "$(DESTDIR)${infodir}/dir" ] || \
+             [ ! -f ${srcdir}/info/dir ] || \
+             ${INSTALL_DATA} ${srcdir}/info/dir "$(DESTDIR)${infodir}/dir"; \
+          info_misc=`$(QUIET_SUBMAKE) $(MAKE) -s -C doc/misc echo-info`; \
           cd ${srcdir}/info ; \
           for elt in ${INFO_NONMISC} $${info_misc}; do \
              test "$(HAVE_MAKEINFO)" = "no" && test ! -f $$elt && continue; \
@@ -732,19 +703,14 @@ install-etc:
 
 ### Build Emacs and install it, stripping binaries while installing them.
 install-strip:
-       $(MAKE) $(MFLAGS) INSTALL_STRIP=-s install
+       $(MAKE) INSTALL_STRIP=-s install
 
 ### Delete all the installed files that the `install' target would
 ### create (but not the noninstalled files such as `make all' would create).
 ###
 ### Don't delete the lisp and etc directories if they're in the source tree.
 uninstall: uninstall-$(NTDIR) uninstall-doc
-       cd lib-src &&                                   \
-        $(MAKE) $(MFLAGS) uninstall                    \
-           prefix="${prefix}" exec_prefix="${exec_prefix}" \
-           bindir="${bindir}" libexecdir="${libexecdir}" \
-           archlibdir="${archlibdir}"
-
+       $(MAKE) -C lib-src uninstall
        -unset CDPATH; \
        for dir in "$(DESTDIR)${lispdir}" "$(DESTDIR)${etcdir}" ; do    \
          if [ -d "$${dir}" ]; then                     \
@@ -761,7 +727,7 @@ uninstall: uninstall-$(NTDIR) uninstall-doc
        done
        -rm -rf "$(DESTDIR)${libexecdir}/emacs/${version}"
        thisdir=`/bin/pwd`; \
-       (info_misc=`cd doc/misc && $(QUIET_SUBMAKE) $(MAKE) -s echo-info`; \
+       (info_misc=`$(QUIET_SUBMAKE) $(MAKE) -s -C doc/misc echo-info`; \
         if cd "$(DESTDIR)${infodir}"; then \
           for elt in ${INFO_NONMISC} $${info_misc}; do \
             (cd "$${thisdir}"; \
@@ -793,35 +759,35 @@ uninstall: uninstall-$(NTDIR) uninstall-doc
 ### in nt/, and its Posix do-nothing shadow.
 uninstall-:
 uninstall-nt:
-       cd $(NTDIR) &&                                  \
-        $(MAKE) $(MFLAGS) uninstall                    \
-           prefix="${prefix}" exec_prefix="${exec_prefix}" \
-           bindir="${bindir}" libexecdir="${libexecdir}" \
-           archlibdir="${archlibdir}"
-
-FRC:
+       $(MAKE) -C $(NTDIR) uninstall
 
 # ==================== Cleaning up and miscellanea ====================
 
 .PHONY: mostlyclean clean distclean bootstrap-clean maintainer-clean extraclean
 
+## Eg:
+## src_clean:
+##     make -C src clean
+define submake_template
+.PHONY: $(1)_$(2)
+$(1)_$(2):
+       $$(MAKE) -C $(1) $(2)
+endef
+
 ### `mostlyclean'
 ###      Like `clean', but may refrain from deleting a few files that people
 ###      normally don't want to recompile.  For example, the `mostlyclean'
 ###      target for GCC does not delete `libgcc.a', because recompiling it
 ###      is rarely necessary and takes a lot of time.
-mostlyclean: FRC
-       cd src      && $(MAKE) $(MFLAGS) mostlyclean
-       cd oldXMenu && $(MAKE) $(MFLAGS) mostlyclean
-       cd lwlib    && $(MAKE) $(MFLAGS) mostlyclean
-       cd lib      && $(MAKE) $(MFLAGS) mostlyclean
-       cd lib-src  && $(MAKE) $(MFLAGS) mostlyclean
-       cd nt       && $(MAKE) $(MFLAGS) mostlyclean
-       -cd doc/emacs     && $(MAKE) $(MFLAGS) mostlyclean
-       -cd doc/misc      && $(MAKE) $(MFLAGS) mostlyclean
-       -cd doc/lispref   && $(MAKE) $(MFLAGS) mostlyclean
-       -cd doc/lispintro && $(MAKE) $(MFLAGS) mostlyclean
-       cd leim     && $(MAKE) $(MFLAGS) mostlyclean
+mostlyclean_dirs = src oldXMenu lwlib lib lib-src nt doc/emacs doc/misc \
+  doc/lispref doc/lispintro
+
+$(foreach dir,$(mostlyclean_dirs),$(eval $(call submake_template,$(dir),mostlyclean)))
+
+mostlyclean: $(mostlyclean_dirs:=_mostlyclean)
+       for dir in test/automated; do \
+         [ ! -d $$dir ] || $(MAKE) -C $$dir mostlyclean; \
+       done
 
 ### `clean'
 ###      Delete all files from the current directory that are normally
@@ -831,25 +797,21 @@ mostlyclean: FRC
 ###      with them.
 ###
 ###      Delete `.dvi' files here if they are not part of the distribution.
-clean: FRC
+clean_dirs = $(mostlyclean_dirs) nextstep
+
+$(foreach dir,$(clean_dirs),$(eval $(call submake_template,$(dir),clean)))
+
+clean: $(clean_dirs:=_clean)
+       for dir in test/automated; do \
+         [ ! -d $$dir ] || $(MAKE) -C $$dir clean; \
+       done
        -rm -f etc/emacs.tmpdesktop
-       cd src      && $(MAKE) $(MFLAGS) clean
-       cd oldXMenu && $(MAKE) $(MFLAGS) clean
-       cd lwlib    && $(MAKE) $(MFLAGS) clean
-       cd lib      && $(MAKE) $(MFLAGS) clean
-       cd lib-src  && $(MAKE) $(MFLAGS) clean
-       cd nt       && $(MAKE) $(MFLAGS) clean
-       -cd doc/emacs     && $(MAKE) $(MFLAGS) clean
-       -cd doc/misc      && $(MAKE) $(MFLAGS) clean
-       -cd doc/lispref   && $(MAKE) $(MFLAGS) clean
-       -cd doc/lispintro && $(MAKE) $(MFLAGS) clean
-       cd leim     && $(MAKE) $(MFLAGS) clean
-       cd nextstep && $(MAKE) $(MFLAGS) clean
 
 ### `bootclean'
 ###      Delete all files that need to be remade for a clean bootstrap.
 top_bootclean=\
        rm -f config.cache config.log
+
 ### `distclean'
 ###      Delete all files from the current directory that are created by
 ###      configuring or building the program.  If you have unpacked the
@@ -859,46 +821,28 @@ top_bootclean=\
 top_distclean=\
        ${top_bootclean}; \
        rm -f config.status config.log~ Makefile stamp-h1 ${SUBDIR_MAKEFILES}
-distclean: FRC
-       cd src      && $(MAKE) $(MFLAGS) distclean
-       cd oldXMenu && $(MAKE) $(MFLAGS) distclean
-       cd lwlib    && $(MAKE) $(MFLAGS) distclean
-       cd lib      && $(MAKE) $(MFLAGS) distclean
-       cd lib-src  && $(MAKE) $(MFLAGS) distclean
-       cd nt       && $(MAKE) $(MFLAGS) distclean
-       cd doc/emacs     && $(MAKE) $(MFLAGS) distclean
-       cd doc/misc      && $(MAKE) $(MFLAGS) distclean
-       cd doc/lispref   && $(MAKE) $(MFLAGS) distclean
-       cd doc/lispintro && $(MAKE) $(MFLAGS) distclean
-       cd leim     && $(MAKE) $(MFLAGS) distclean
-       cd lisp     && $(MAKE) $(MFLAGS) distclean
-       cd nextstep && $(MAKE) $(MFLAGS) distclean
-       for dir in test/automated admin/unidata; do \
-         [ ! -d $$dir ] || (cd $$dir && $(MAKE) $(MFLAGS) distclean); \
+
+distclean_dirs = $(clean_dirs) leim lisp
+
+$(foreach dir,$(distclean_dirs),$(eval $(call submake_template,$(dir),distclean)))
+
+distclean: $(distclean_dirs:=_distclean)
+       for dir in test/automated admin/grammars admin/unidata; do \
+         [ ! -d $$dir ] || $(MAKE) -C $$dir distclean; \
        done
        ${top_distclean}
 
 ### `bootstrap-clean'
 ###      Delete everything that can be reconstructed by `make' and that
 ###      needs to be deleted in order to force a bootstrap from a clean state.
-bootstrap-clean: FRC
-       cd src      && $(MAKE) $(MFLAGS) bootstrap-clean
-       cd oldXMenu && $(MAKE) $(MFLAGS) maintainer-clean
-       cd lwlib    && $(MAKE) $(MFLAGS) maintainer-clean
-       cd lib      && $(MAKE) $(MFLAGS) maintainer-clean
-       cd lib-src  && $(MAKE) $(MFLAGS) maintainer-clean
-       cd nt       && $(MAKE) $(MFLAGS) maintainer-clean
-       -cd doc/emacs     && $(MAKE) $(MFLAGS) maintainer-clean
-       -cd doc/misc      && $(MAKE) $(MFLAGS) maintainer-clean
-       -cd doc/lispref   && $(MAKE) $(MFLAGS) maintainer-clean
-       -cd doc/lispintro && $(MAKE) $(MFLAGS) maintainer-clean
-       cd leim     && $(MAKE) $(MFLAGS) maintainer-clean
-       cd lisp     && $(MAKE) $(MFLAGS) bootstrap-clean
-       cd nextstep && $(MAKE) $(MFLAGS) maintainer-clean
-       for dir in test/automated admin/unidata; do \
-         [ ! -d $$dir ] || (cd $$dir && $(MAKE) $(MFLAGS) bootstrap-clean); \
+$(foreach dir,$(distclean_dirs),$(eval $(call submake_template,$(dir),bootstrap-clean)))
+
+bootstrap-clean: $(distclean_dirs:=_bootstrap-clean)
+       for dir in test/automated admin/grammars admin/unidata; do \
+         [ ! -d $$dir ] || $(MAKE) -C $$dir bootstrap-clean; \
        done
        [ ! -f config.log ] || mv -f config.log config.log~
+       rm -rf ${srcdir}/info
        ${top_bootclean}
 
 ### `maintainer-clean'
@@ -915,11 +859,14 @@ bootstrap-clean: FRC
 top_maintainer_clean=\
        ${top_distclean}; \
        rm -fr autom4te.cache
-maintainer-clean: bootstrap-clean FRC
-       cd src  && $(MAKE) $(MFLAGS) maintainer-clean
-       cd lisp && $(MAKE) $(MFLAGS) maintainer-clean
-       for dir in test/automated admin/unidata; do \
-         [ ! -d $$dir ] || (cd $$dir && $(MAKE) $(MFLAGS) maintainer-clean); \
+
+maintainer_clean_dirs = src leim lisp
+
+$(foreach dir,$(maintainer_clean_dirs),$(eval $(call submake_template,$(dir),maintainer-clean)))
+
+maintainer-clean: bootstrap-clean $(maintainer_clean_dirs:=_maintainer-clean)
+       for dir in test/automated admin/grammars admin/unidata; do \
+         [ ! -d $$dir ] || $(MAKE) -C $$dir maintainer-clean; \
        done
        ${top_maintainer_clean}
 
@@ -927,8 +874,12 @@ maintainer-clean: bootstrap-clean FRC
 ### says GCC supports it, and that's where the configuration part of
 ### the coding standards seem to come from.  It's like distclean, but
 ### it deletes backup and autosave files too.
-extraclean:
-       for i in ${SUBDIR}; do (cd $$i; $(MAKE) $(MFLAGS) extraclean); done
+### Note that we abuse this in some subdirectories (eg leim),
+### to delete some generated files that are slow to rebuild.
+$(foreach dir,$(SUBDIR),$(eval $(call submake_template,$(dir),extraclean)))
+
+## FIXME this is busted because most of these do not have extraclean rules.
+extraclean: $(SUBDIR:=_extraclean)
        ${top_maintainer_clean}
        -rm -f config-tmp-*
        -rm -f *~ \#*
@@ -937,14 +888,14 @@ extraclean:
 # even when the build directory and source dir are different.
 .PHONY: TAGS tags
 TAGS tags: lib lib-src src
-       cd src; $(MAKE) $(MFLAGS) tags
+       $(MAKE) -C src tags
 
 check: all
        @if test ! -d test/automated; then \
          echo "You do not seem to have the test/ directory."; \
          echo "Maybe you are using a release tarfile, rather than a repository checkout."; \
        else \
-         cd test/automated && $(MAKE) $(MFLAGS) check; \
+         $(MAKE) -C test/automated check; \
        fi
 
 dist:
@@ -958,10 +909,10 @@ PSS   = lispref-ps   lispintro-ps   emacs-ps   misc-ps
 
 DOCS = $(DVIS) $(HTMLS) $(INFOS) $(PDFS) $(PSS)
 $(DOCS):
-       t=$@; IFS=-; set $$t; IFS=; cd doc/$$1 && $(MAKE) $(MFLAGS) $$2
+       t=$@; IFS=-; set $$t; IFS=; $(MAKE) -C doc/$$1 $$2
 
 .PHONY: $(DOCS) docs pdf ps
-.PHONY: info dvi dist check html info-real force-info check-info-dir
+.PHONY: info dvi dist check html info-real info-dir check-info
 
 ## TODO add etc/refcards.
 docs: $(DOCS)
@@ -971,6 +922,28 @@ info-real: $(INFOS)
 pdf: $(PDFS)
 ps: $(PSS)
 
+info-dir: ${srcdir}/info/dir
+
+## Not strictly necessary, but speeds things up a bit by stopping
+## the info-dir rule from running when not needed.
+## Hopefully doc/misc/*.texi is not too long for some systems?
+info_dir_deps = ${srcdir}/build-aux/dir_top \
+       ${srcdir}/doc/emacs/emacs.texi \
+       ${srcdir}/doc/lispintro/emacs-lisp-intro.texi \
+       ${srcdir}/doc/lispref/elisp.texi ${srcdir}/doc/misc/*.texi
+
+## It would be much simpler if info/dir was only created in the
+## installation location by the install-info rule, but we also
+## need one in the source directory for people running uninstalled.
+## FIXME it would be faster to use the install-info program if we have it,
+## but then we would need to depend on info-real, which would
+## slow down parallelization.
+${srcdir}/info/dir: ${info_dir_deps}
+       tempfile=info-dir.$$$$; \
+       rm -f $${tempfile}; \
+       thisdir=`pwd`; \
+       (cd ${srcdir} && ./build-aux/make-info-dir $${thisdir}/$${tempfile}); \
+       ${srcdir}/build-aux/move-if-change $${tempfile} ${srcdir}/info/dir
 
 INSTALL_DVI = install-emacs-dvi install-lispref-dvi \
        install-lispintro-dvi install-misc-dvi
@@ -985,7 +958,7 @@ INSTALL_DOC = $(INSTALL_DVI) $(INSTALL_HTML) $(INSTALL_PDF) $(INSTALL_PS)
 ## Install non .info forms of the documentation.
 ## TODO add etc/refcards.
 $(INSTALL_DOC):
-       t=$@; IFS=-; set $$t; IFS=; cd doc/$$2 && $(MAKE) $(MFLAGS) $$1-$$3
+       t=$@; IFS=-; set $$t; IFS=; $(MAKE) -C doc/$$2 $$1-$$3
 
 .PHONY: $(INSTALL_DOC) install-doc
 .PHONY: install-dvi install-html install-pdf install-ps
@@ -1008,7 +981,7 @@ UNINSTALL_PS = uninstall-emacs-ps uninstall-lispref-ps \
 UNINSTALL_DOC = $(UNINSTALL_DVI) $(UNINSTALL_HTML) $(UNINSTALL_PDF) $(UNINSTALL_PS)
 
 $(UNINSTALL_DOC):
-       t=$@; IFS=-; set $$t; IFS=; cd doc/$$2 && $(MAKE) $(MFLAGS) $$1-$$3
+       t=$@; IFS=-; set $$t; IFS=; $(MAKE) -C doc/$$2 $$1-$$3
 
 .PHONY: $(UNINSTALL_DOC) uninstall-doc
 .PHONY: uninstall-dvi uninstall-html uninstall-pdf uninstall-ps
@@ -1020,7 +993,6 @@ uninstall-pdf: $(UNINSTALL_PDF)
 uninstall-ps: $(UNINSTALL_PS)
 
 
-force-info:
 # Note that man/Makefile knows how to put the info files in $(srcdir),
 # so we can do ok running make in the build dir.
 # This used to have a clause that exited with an error if MAKEINFO = no.
@@ -1032,32 +1004,35 @@ force-info:
 # would require changing every rule in doc/ that builds an info file,
 # and it's not worth it.  This case is only relevant if you download a
 # release, then change the .texi files.
-info: force-info
+info:
        @if test "$(HAVE_MAKEINFO)" = "no"; then \
          echo "Configured --without-makeinfo, not building manuals" ; \
        else \
-         $(MAKE) $(MFLAGS) info-real ; \
+         $(MAKE) info-real info-dir; \
        fi
 
-# The info/dir file must be updated by hand when new manuals are added.
-# Cannot add an info/dir entry for efaq-w32 since it is not installed
-# on all platforms.
-check-info-dir: info
+## build-aux/make-info-dir expects only certain dircategories.
+check-info: info
        cd info ; \
-       missing= ; \
+       bad= ; \
        for file in *; do \
          test -f "$${file}" || continue ; \
          case $${file} in \
-           *-[0-9]*|COPYING|dir|efaq-w32*) continue ;; \
+           *-[0-9]*|COPYING|dir) continue ;; \
          esac ; \
-         file=`echo $${file} | sed 's/\.info//'` ; \
-         grep -q -F ": ($${file})." dir || missing="$${missing} $${file}" ; \
+         cat=`sed -n 's/^INFO-DIR-SECTION //p' $${file}`; \
+         case $${cat} in \
+          "Texinfo documentation system" | "Emacs"| "Emacs lisp" | \
+           "Emacs editing modes" | "Emacs network features" | \
+          "Emacs misc features" | "Emacs lisp libraries" ) : ;; \
+          *)  bad="$${bad} $${file}" ;; \
+         esac; \
        done ; \
-       if test -n "$${missing}"; then \
-         echo "Missing info/dir entries: $${missing}" ; \
+       if test -n "$${bad}"; then \
+         echo "Unexpected dircategory in: $${bad}" ; \
          exit 1 ; \
        fi ; \
-       echo "info/dir is OK"
+       echo "info files are OK"
 
 #### Bootstrapping.
 
@@ -1071,10 +1046,10 @@ check-info-dir: info
 #  * Run autogen.sh.
 #  * Rebuild Makefile, to update the build procedure itself.
 #  * Do the actual build.
-bootstrap: bootstrap-clean FRC
+bootstrap: bootstrap-clean
        cd $(srcdir) && ./autogen.sh
-       $(MAKE) $(MFLAGS) MAKEFILE_NAME=force-Makefile force-Makefile
-       $(MAKE) $(MFLAGS) info all
+       $(MAKE) MAKEFILE_NAME=force-Makefile force-Makefile
+       $(MAKE) all
 
 .PHONY: check-declare
 
@@ -1083,5 +1058,4 @@ check-declare:
          echo "You must build Emacs to use this command"; \
          exit 1; \
        fi
-       cd leim && $(MAKE) $(MFLAGS) $@
-       cd lisp && $(MAKE) $(MFLAGS) $@
+       $(MAKE) -C lisp $@