Motivated by automake bug#11806.
Traditionally, automake byte-compiled emacs-lisp '.el' files by invoking
'elisp-comp' on all of them in a bulk; this involved complex timestamping
and file-locking logic. It was also brittle in any slightly-unusual
setup, because 'elisp-comp' operated by copying all of the elisp files
to be compiled into a temporary sub-directory and compiling them in there,
the copying the resulting byte-compile files back in the build directory.
This patch removes all of that juggling and chicanery in favour of
defining a much simpler '.el.elc' suffix rule. Not only this is simpler,
but it also interacts better with "make -jN" calls, which are becoming
more and more common and useful on today's increasingly multicore systems.
* Makefile.am (dist_script_DATA): Remove 'elisp-comp'.
* automake.in (@common_files): Likewise.
(handle_emacs_lisp): Do not require 'elisp-comp'.
* doc/automake.texi: Remove references to 'elisp-comp'.
* lib/am/lisp.am: Define elisp compilation via a suffix rule; this
basically amounts to a complete re-write of the lisp byte-compilation
rules.
* lib/elisp-comp: Remove.
* t/add-missing.tap: Remove elisp-comp test.
* t/dist-auxdir-many-subdirs.sh: Remove reference to elisp-comp.
* t/primary-prefix-invalid-couples.tap: Likewise.
* t/primary-prefix-valid-couples.sh: Likewise.
* t/lisp4.sh: Remove reference to elc-stamp.
* t/lisp5.sh: Likewise.
* t/lisp6.sh: Likewise.
* t/lisp3.sh: Likewise. Also remove the recompilation check that
involves a (message) call.
* t/lisp7.sh: Remove check for "Warnings can be ignored". Remove
reference to elc-stamp.
* t/lisp8.sh: Likewise.
* t/lispdry.sh: Remove references to elc-stamp.
Acked-by: Stefano Lattarini <stefano.lattarini@gmail.com>
Signed-off-by: Stefano Lattarini <stefano.lattarini@gmail.com>
lib/mdate-sh \
lib/missing \
lib/mkinstalldirs \
- lib/elisp-comp \
lib/ylwrap \
lib/depcomp \
lib/compile \
(qw(ABOUT-GNU ABOUT-NLS AUTHORS BACKLOG COPYING COPYING.DOC COPYING.LIB
COPYING.LESSER ChangeLog INSTALL NEWS README THANKS TODO
ar-lib compile config.guess config.rpath
- config.sub depcomp elisp-comp install-sh libversion.in mdate-sh
+ config.sub depcomp install-sh libversion.in mdate-sh
missing mkinstalldirs py-compile texinfo.tex ylwrap),
@libtool_files, @libtool_sometimes);
require_variables ($elfiles[0][0], "Emacs Lisp sources seen", TRUE,
'EMACS', 'lispdir');
- require_conf_file ($elfiles[0][0], FOREIGN, 'elisp-comp');
- &define_variable ('elisp_comp', "$am_config_aux_dir/elisp-comp", INTERNAL);
}
# Handle Python
that is then used by the automatic dependency tracking feature
(@pxref{Dependencies}).
-@item elisp-comp
-This program is used to byte-compile Emacs Lisp code.
-
@item install-sh
This is a replacement for the @command{install} program that works on
platforms where @command{install} is unavailable or unusable.
@file{config.guess},
@file{config.sub},
@file{depcomp},
-@file{elisp-comp},
@file{compile},
@file{install-sh},
@file{ltmain.sh},
## Building. ##
## ---------- ##
-elc-stamp: $(LISP)
- @echo 'WARNING: Warnings can be ignored. :-)'
- @rm -f elc-temp && touch elc-temp
- if test "$(EMACS)" != no; then \
-## Make sure "$@" isn't empty initially.
- set x; \
-## Populate "$@" with elisp files (found in the current directory
-## or in $srcdir).
- list='$(LISP)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- set x "$$@" "$$d$$p"; shift; \
- done; \
-## Finally call elisp-comp for all files.
- shift; \
- abs_srcdir="$(abs_srcdir)" EMACS="$(EMACS)" $(SHELL) \
- $(elisp_comp) "$$@" || exit 1; \
- else : ; fi
- @mv -f elc-temp $@
-
-## Do not use $(ELCFILES) as target, because it may have been emptied
-## by the user (to disable byte-compilation), and POSIX does not allow
-## an empty target.
-$(am__ELCFILES): elc-stamp
-## Recover from the removal of $@.
-##
-## Do not call "make elc-stamp" if emacs is not available, because it would
-## be useless.
-##
-## If "make -n" is called, do not execute any command in the recipe that
-## changes the tree; however, invoke the recursive make for debuggability.
- @if $(am__make_dryrun); then dry=:; else dry=; fi; \
- if test "$(EMACS)" != no && test ! -f $@; then \
-## If "make -j" is used and more than one file has been erased, several
-## processes can execute this block. We have to make sure that only
-## the first one will run "$(MAKE) $(AM_MAKEFLAGS) elc-stamp", and the
-## other ones will wait.
-##
-## There is a race here if only one child of make receive a signal.
-## In that case the build may fail. We remove elc-stamp when we receive
-## a signal so we are sure the build will succeed the next time.
- $$dry trap 'rm -rf elc-lock elc-stamp' 1 2 13 15; \
- if $$dry mkdir elc-lock 2>/dev/null; then \
-## This code is being executed by the first process.
- $$dry rm -f elc-stamp; \
- $(MAKE) $(AM_MAKEFLAGS) elc-stamp; \
- $$dry rmdir elc-lock; \
- else \
-## This code is being executed by the follower processes.
-## Wait until the first process is done.
- while test -d elc-lock && test -z "$$dry"; do sleep 1; done; \
-## Succeed if and only if the first process succeeded.
- $$dry test -f elc-stamp; exit $$?; \
- fi; \
- else : ; fi
+.el.elc:
+## We add $(abs_builddir) and $(abs_srcdir) to load-path, so that any
+## .el files that $< depends upon can be found (including generated
+## ones). The destination file is normally determined by appending "c"
+## to the input (which would put it in $(srcdir)), so we override
+## that, too.
+ if test "$(EMACS)" != "no"; then \
+ $(EMACS) -q --batch \
+ --eval "(setq load-path (cons \"$(abs_builddir)\" load-path))" \
+ --eval "(setq load-path (cons \"$(abs_srcdir)\" load-path))" \
+ --eval "(defun byte-compile-dest-file (f) \"$@\")" \
+ --eval "(unless (byte-compile-file \"$<\") (kill-emacs 1))"; \
+ else :; fi
## ------------ ##
.PHONY clean-am: clean-lisp
clean-lisp:
- -rm -f elc-stamp $(ELCFILES)
+ -rm -f $(ELCFILES)
## -------------- ##
+++ /dev/null
-#!/bin/sh
-# Copyright (C) 1995-2012 Free Software Foundation, Inc.
-
-scriptversion=2012-07-05.17; # UTC
-
-# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1995.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# This file is maintained in Automake, please report
-# bugs to <bug-automake@gnu.org> or send patches to
-# <automake-patches@gnu.org>.
-
-case $1 in
- '')
- echo "$0: No files. Try '$0 --help' for more information." 1>&2
- exit 1;
- ;;
- -h | --h*)
- cat <<\EOF
-Usage: elisp-comp [--help] [--version] FILES...
-
-This script byte-compiles all '.el' files listed as FILES using GNU
-Emacs, and put the resulting '.elc' files into the current directory,
-so disregarding the original directories used in '.el' arguments.
-
-This script manages in such a way that all Emacs LISP files to
-be compiled are made visible between themselves, in the event
-they require or load-library one another.
-
-Report bugs to <bug-automake@gnu.org>.
-EOF
- exit $?
- ;;
- -v | --v*)
- echo "elisp-comp $scriptversion"
- exit $?
- ;;
-esac
-
-if test -z "$EMACS" || test "$EMACS" = "t"; then
- # Value of "t" means we are running in a shell under Emacs.
- # Just assume Emacs is called "emacs".
- EMACS=emacs
-fi
-
-tempdir=elc.$$
-
-# Cleanup the temporary directory on exit.
-trap 'ret=$?; rm -rf "$tempdir" && exit $ret' 0
-do_exit='(exit $ret); exit $ret'
-trap "ret=129; $do_exit" 1
-trap "ret=130; $do_exit" 2
-trap "ret=141; $do_exit" 13
-trap "ret=143; $do_exit" 15
-
-mkdir $tempdir
-cp "$@" $tempdir
-
-(
- cd $tempdir
- echo "(setq load-path (cons nil (cons \"$abs_srcdir\" load-path)))" > script
- $EMACS -batch -q -l script -f batch-byte-compile *.el || exit $?
- mv *.elc ..
-) || exit $?
-
-(exit 0); exit 0
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
-# time-stamp-end: "; # UTC"
-# End:
check_ <<'END'
== Name ==
-elisp-comp
-== Files ==
-elisp-comp
-== configure.ac ==
-AM_PATH_LISPDIR
-== Makefile.am ==
-lisp_LISP = foo.el
-END
-
-check_ <<'END'
-== Name ==
py-compile
== Files ==
py-compile
foo_SOURCES = foo.c
## For py-compile.
python_PYTHON = bar.py
- ## For elisp-comp.
- lisp_LISP = baz.el
## For test-driver.
TESTS =
END
missing
depcomp
py-compile
- elisp-comp
test-driver
'
test -f am-one.elc
test -f am-two.elc
test -f am-three.elc
-test -f elc-stamp
# Make sure we can recover from a deletion.
rm -f am-one.elc
$MAKE uninstall
find _inst | $EGREP '\.elc?$' && exit 1
-# Make sure we build all files when any of them change.
-# (We grep a message to make sure the compilation happens.)
-unique=0a3346e2af8a689b85002b53df09142a
-$sleep
-echo "(message \"$unique\")(provide 'am-three)" > am-three.el
-$MAKE >output 2>&1 || { cat output; exit 1; }
-cat output
-grep $unique output
-
# It should also work for VPATH-builds.
$MAKE distcheck
test ! -f am-one.elc
test ! -f am-two.elc
test ! -f am-three.elc
- test ! -f elc-stamp
install-test: install
test -f "$(lispdir)/am-one.el"
test ! -f am-one.elc
test ! -f am-two.elc
test ! -f am-three.elc
- test ! -f elc-stamp
install-test: install
test -f "$(lispdir)/am-one.el"
test -f am-one.elc
test ! -e am-two.elc
test -f am-three.elc
-test -f elc-stamp
$MAKE install
test -f lisp/am-one.el
test ! -e am-one.elc
test ! -e am-two.elc
test ! -e am-three.elc
-test ! -e elc-stamp
./configure --with-lispdir="$cwd/lisp" want_two=1
test -f am-one.elc
test -f am-two.elc
test -f am-three.elc
-test -f elc-stamp
# Let's mutilate the source tree, to check the recover rule.
rm -f am-*.elc
test -f am-one.elc
test -f am-two.elc
test -f am-three.elc
-test -f elc-stamp
$MAKE install
test -f lisp/am-one.el
test ! -e am-one.elc
test ! -e am-two.elc
test ! -e am-three.elc
-test ! -e elc-stamp
:
$MAKE >stdout || { cat stdout; exit 1; }
cat stdout
-test 1 -eq $(grep -c 'Warnings can be ignored' stdout)
test ! -e am-one.elc
test ! -e am-two.elc
test ! -e am-three.elc
-test -f elc-stamp
$MAKE distcheck
$MAKE -j >>stdout || { cat stdout; exit 1; }
cat stdout
-test 1 -eq $(grep -c 'Warnings can be ignored' stdout)
test -f am-one.elc
test -f am-two.elc
test -f am-three.elc
-test -f elc-stamp
rm -f am-*.elc
$MAKE -j >>stdout || { cat stdout; exit 1; }
cat stdout
-test 1 -eq $(grep -c 'Warnings can be ignored' stdout)
test -f am-one.elc
test -f am-two.elc
test -f am-three.elc
-test -f elc-stamp
:
test -f am-one.elc
test -f am-two.elc
test -f am-three.elc
-test -f elc-stamp
-rm -f am-*.elc elc-stamp
+rm -f am-*.elc
chmod a-w .
test ! -e am-one.elc
test ! -e am-two.elc
test ! -e am-three.elc
-test ! -e elc-stamp
:
: > ar-lib
: > ltmain.sh
: > texinfo.tex
-: > elisp-comp
: > py-compile
: > config.guess
: > config.sub
echo '@setfilename foo' > foo.texi
: > texinfo.tex
: > py-compile
-: > elisp-comp
: > ar-lib
# Setup Makefile.am.