Mercurial > hg > xemacs-beta
diff lisp/update-elc-2.el @ 1298:1b4bc72f433e
[xemacs-hg @ 2003-02-14 12:05:06 by ben]
speedups to build process
autoload.el: Factor out common code in generate-{c-,}file-autoloads-1 into new
function generate-autoload-ish-1. \(I was originally going to use
this for custom as well but ended up thinking better of it.)
cus-dep.el: Cache the old computed values in custom-load.el and reuse them as
necessary, to speed up running cus-dep (which would take 25-30
seconds to do all files in lisp/*, lisp/*/* on my Pentium III
700). Use `message' not `princ' to get correct newline behavior.
Output messages showing each file we do actually process.
update-elc-2.el: Rewrite algorithm to be much faster -- cache calls to
directory-files and don't make needless calls to file-exists-p,
file-directory-p because they're way way slow.
Autoload early and only when update-elc has told us to.
update-elc.el: If no files need byte compilation, signal to update-elc-2 to do
any necessary autoload updating (using the file REBUILD_AUTOLOADS)
rather than doing it ourselves, which would be way slow. Ignore
updates to custom-load.el and auto-autoloads.el when checking to
see whether autoloads need updating. Optimize out many
unnecessary calls to file-exists-p to speed it up somewhat. (####
The remaining time is 50% or more in locate-file; this is
presumably because, even though it has a cache, it's still
statting each file to determine it's actually there. By calling
directory-files ourselves, building a tree, and then looking in
that tree, we could drastically shorten the time needed to do the
locate operation.)
author | ben |
---|---|
date | Fri, 14 Feb 2003 12:05:07 +0000 |
parents | 465bd3c7d932 |
children | f99d3d25df86 |
line wrap: on
line diff
--- a/lisp/update-elc-2.el Fri Feb 14 11:50:36 2003 +0000 +++ b/lisp/update-elc-2.el Fri Feb 14 12:05:07 2003 +0000 @@ -69,6 +69,8 @@ "^version\\.el$" "^very-early-lisp\\.el$")) +(defvar dirfiles-table (make-hash-table :test 'equal)) + ;; SEEN accumulates the list of already-handled dirs. (defun do-update-elc-2 (dir compile-stage-p seen) (setq dir (file-name-as-directory dir)) @@ -76,65 +78,104 @@ (unless (member (file-truename dir) seen) (push (file-truename dir) seen) - ;; Do this directory. - (if compile-stage-p - ;; Stage 2: Recompile necessary .els - (let ((files (directory-files dir t "\\.el$")) - file file-c) - (while (setq file (car files)) - (setq files (cdr files)) - (setq file-c (concat file "c")) - (when (and (file-exists-p file) - (or (not (file-exists-p file-c)) - (file-newer-than-file-p file file-c)) - (let (ignore) - (mapcar - #'(lambda (regexp) - (if (string-match regexp - (file-name-nondirectory file)) - (setq ignore t))) - update-elc-ignored-files) - (not ignore))) - (byte-compile-file file)))) + (let ((files (or (gethash dir dirfiles-table) + (directory-files dir t nil t)))) + + ;; Do this directory. + (if compile-stage-p + ;; Stage 2: Recompile necessary .els + (dolist (file files) + (when (string-match "\\.el$" file) + (let ((file-c (concat file "c"))) + (when (and (not (member file-c files)) + ;; no need to check for out-of-date-ness because + ;; that was already done, and .elc removed. + (let (ignore) + (mapcar + #'(lambda (regexp) + (if (string-match + regexp + (file-name-nondirectory file)) + (setq ignore t))) + update-elc-ignored-files) + (not ignore))) + (byte-compile-file file))))) - ;; Stage 1. - ;; Remove out-of-date elcs - (let ((files (directory-files dir t "\\.el$")) - file file-c) - (while (setq file (car files)) - (setq files (cdr files)) - (setq file-c (concat file "c")) - (when (and (file-exists-p file-c) - (file-newer-than-file-p file file-c)) - (message "Removing out-of-date %s" file-c) - (delete-file file-c)))) - ;; Remove elcs without corresponding el - (let ((files (directory-files dir t "\\.elc$")) - file file-c) - (while (setq file-c (car files)) - (setq files (cdr files)) - (setq file (replace-in-string file-c "c$" "")) - (when (and (file-exists-p file-c) - (not (file-exists-p file))) - (message "Removing %s; no corresponding .el" file-c) - (delete-file file-c))))) + ;; Stage 1. + ;; Remove out-of-date elcs + (let (deleted) + (dolist (file files) + (when (string-match "\\.el$" file) + (let ((file-c (concat file "c"))) + (when (and (member file-c files) + (file-newer-than-file-p file file-c)) + (message "Removing out-of-date %s" file-c) + (delete-file file-c) + (push file-c deleted))))) - ;; We descend recursively - (let ((dirs (directory-files dir t nil t)) - dir) - (while (setq dir (pop dirs)) - (when (and (not (member (file-name-nondirectory dir) - update-elc-ignored-dirs)) - (file-directory-p dir)) - (do-update-elc-2 dir compile-stage-p seen)))) + ;; Remove elcs without corresponding el + (dolist (file-c files) + (when (string-match "\\.elc$" file-c) + (let ((file (replace-in-string file-c "c$" ""))) + (when (not (member file files)) + (message "Removing %s; no corresponding .el" file-c) + (delete-file file-c) + (push file-c deleted))))) - )) + (setq files (set-difference files deleted)))) + + (puthash dir files dirfiles-table) + + ;; We descend recursively. On my Windows machine, it is much faster + ;; to call directory-files again to recompute than to call + ;; file-directory-p on each member of the files list. + (dolist (dir (directory-files dir t nil t 'dir)) + (when (not (member (file-name-nondirectory dir) + update-elc-ignored-dirs)) + (do-update-elc-2 dir compile-stage-p seen)))))) (defun batch-update-elc-2 () (defvar command-line-args-left) (unless noninteractive (error "`batch-update-elc-2' is to be used only with -batch")) (let ((dir (car command-line-args-left))) + ;; don't depend on being able to autoload `update-autoload-files'! + (load "autoload") + (load "bytecomp") + (load "byte-optimize") + ;; #### the API used here is deprecated, convert to one with explicit + ;; arguments when it is available + ;; update-elc.el signals us to rebuild the autoloads when necessary. + ;; in some cases it will rebuild the autoloads itself, but doing it this + ;; way is slow, so we avoid it when possible. + (when (file-exists-p "../src/REBUILD_AUTOLOADS") + (let ((generated-autoload-file (expand-file-name "auto-autoloads.el" dir)) + (autoload-package-name "auto")) ; feature prefix + (update-autoload-files (list dir)) + (byte-recompile-file generated-autoload-file 0)) + (when (featurep 'mule) + (let* ((muledir (expand-file-name "../lisp/mule" (file-truename dir))) + (generated-autoload-file + (expand-file-name "auto-autoloads.el" muledir)) + (autoload-package-name "mule")) ; feature prefix + (update-autoload-files (list muledir)) + (byte-recompile-file generated-autoload-file 0)))) + (when (featurep 'modules) + (let* ((moddir (expand-file-name "../modules" (file-truename dir))) + (generated-autoload-file + (expand-file-name "auto-autoloads.el" moddir)) + (autoload-package-name "modules")) ; feature prefix + (update-autoload-files + (delete (concat (file-name-as-directory moddir) ".") + (delete (concat (file-name-as-directory moddir) "..") + (directory-files moddir t nil nil 0))) + t) + (byte-recompile-file generated-autoload-file 0))) + ;; now load the (perhaps newly rebuilt) autoloads; we were called with + ;; -no-autoloads so they're not already loaded. + (load "../lisp/auto-autoloads") + (when (featurep 'mule) + (load "../lisp/mule/auto-autoloads")) ;; We remove all the bad .elcs before any byte-compilation, because ;; there may be dependencies between one .el and another (even across ;; directories), and we don't want to load an out-of-date .elc while @@ -146,32 +187,6 @@ (message "Recompiling updated .els in directory tree `%s'..." dir) (do-update-elc-2 dir t nil) (message "Recompiling updated .els in directory tree `%s'...done" dir) - ;; don't depend on being able to autoload `update-autoload-files'! - (load "autoload") - ;; #### the API used here is deprecated, convert to one with explicit - ;; arguments when it is available - (let ((generated-autoload-file (expand-file-name "auto-autoloads.el" dir)) - (autoload-package-name "auto")) ; feature prefix - (update-autoload-files (list dir)) - (byte-recompile-file generated-autoload-file 0)) - (when (featurep 'modules) - (let* ((moddir (expand-file-name "../modules" (file-truename dir))) - (generated-autoload-file - (expand-file-name "auto-autoloads.el" moddir)) - (autoload-package-name "modules")) ; feature prefix - (update-autoload-files - (delete (concat (file-name-as-directory moddir) ".") - (delete (concat (file-name-as-directory moddir) "..") - (directory-files moddir t nil nil 0))) - t) - (byte-recompile-file generated-autoload-file 0))) - (when (featurep 'mule) - (let* ((muledir (expand-file-name "../lisp/mule" (file-truename dir))) - (generated-autoload-file - (expand-file-name "auto-autoloads.el" muledir)) - (autoload-package-name "mule")) ; feature prefix - (update-autoload-files (list muledir)) - (byte-recompile-file generated-autoload-file 0))) ;; likewise here. (load "cus-dep") (Custom-make-dependencies dir)