Mercurial > hg > xemacs-beta
comparison 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 |
comparison
equal
deleted
inserted
replaced
1297:6c21360a544b | 1298:1b4bc72f433e |
---|---|
67 "^site-load\\.el$" | 67 "^site-load\\.el$" |
68 "^site-init\\.el$" | 68 "^site-init\\.el$" |
69 "^version\\.el$" | 69 "^version\\.el$" |
70 "^very-early-lisp\\.el$")) | 70 "^very-early-lisp\\.el$")) |
71 | 71 |
72 (defvar dirfiles-table (make-hash-table :test 'equal)) | |
73 | |
72 ;; SEEN accumulates the list of already-handled dirs. | 74 ;; SEEN accumulates the list of already-handled dirs. |
73 (defun do-update-elc-2 (dir compile-stage-p seen) | 75 (defun do-update-elc-2 (dir compile-stage-p seen) |
74 (setq dir (file-name-as-directory dir)) | 76 (setq dir (file-name-as-directory dir)) |
75 ;; Only scan this sub-tree if we haven't been here yet. | 77 ;; Only scan this sub-tree if we haven't been here yet. |
76 (unless (member (file-truename dir) seen) | 78 (unless (member (file-truename dir) seen) |
77 (push (file-truename dir) seen) | 79 (push (file-truename dir) seen) |
78 | 80 |
79 ;; Do this directory. | 81 (let ((files (or (gethash dir dirfiles-table) |
80 (if compile-stage-p | 82 (directory-files dir t nil t)))) |
81 ;; Stage 2: Recompile necessary .els | 83 |
82 (let ((files (directory-files dir t "\\.el$")) | 84 ;; Do this directory. |
83 file file-c) | 85 (if compile-stage-p |
84 (while (setq file (car files)) | 86 ;; Stage 2: Recompile necessary .els |
85 (setq files (cdr files)) | 87 (dolist (file files) |
86 (setq file-c (concat file "c")) | 88 (when (string-match "\\.el$" file) |
87 (when (and (file-exists-p file) | 89 (let ((file-c (concat file "c"))) |
88 (or (not (file-exists-p file-c)) | 90 (when (and (not (member file-c files)) |
91 ;; no need to check for out-of-date-ness because | |
92 ;; that was already done, and .elc removed. | |
93 (let (ignore) | |
94 (mapcar | |
95 #'(lambda (regexp) | |
96 (if (string-match | |
97 regexp | |
98 (file-name-nondirectory file)) | |
99 (setq ignore t))) | |
100 update-elc-ignored-files) | |
101 (not ignore))) | |
102 (byte-compile-file file))))) | |
103 | |
104 ;; Stage 1. | |
105 ;; Remove out-of-date elcs | |
106 (let (deleted) | |
107 (dolist (file files) | |
108 (when (string-match "\\.el$" file) | |
109 (let ((file-c (concat file "c"))) | |
110 (when (and (member file-c files) | |
89 (file-newer-than-file-p file file-c)) | 111 (file-newer-than-file-p file file-c)) |
90 (let (ignore) | 112 (message "Removing out-of-date %s" file-c) |
91 (mapcar | 113 (delete-file file-c) |
92 #'(lambda (regexp) | 114 (push file-c deleted))))) |
93 (if (string-match regexp | 115 |
94 (file-name-nondirectory file)) | 116 ;; Remove elcs without corresponding el |
95 (setq ignore t))) | 117 (dolist (file-c files) |
96 update-elc-ignored-files) | 118 (when (string-match "\\.elc$" file-c) |
97 (not ignore))) | 119 (let ((file (replace-in-string file-c "c$" ""))) |
98 (byte-compile-file file)))) | 120 (when (not (member file files)) |
99 | 121 (message "Removing %s; no corresponding .el" file-c) |
100 ;; Stage 1. | 122 (delete-file file-c) |
101 ;; Remove out-of-date elcs | 123 (push file-c deleted))))) |
102 (let ((files (directory-files dir t "\\.el$")) | 124 |
103 file file-c) | 125 (setq files (set-difference files deleted)))) |
104 (while (setq file (car files)) | 126 |
105 (setq files (cdr files)) | 127 (puthash dir files dirfiles-table) |
106 (setq file-c (concat file "c")) | 128 |
107 (when (and (file-exists-p file-c) | 129 ;; We descend recursively. On my Windows machine, it is much faster |
108 (file-newer-than-file-p file file-c)) | 130 ;; to call directory-files again to recompute than to call |
109 (message "Removing out-of-date %s" file-c) | 131 ;; file-directory-p on each member of the files list. |
110 (delete-file file-c)))) | 132 (dolist (dir (directory-files dir t nil t 'dir)) |
111 ;; Remove elcs without corresponding el | 133 (when (not (member (file-name-nondirectory dir) |
112 (let ((files (directory-files dir t "\\.elc$")) | 134 update-elc-ignored-dirs)) |
113 file file-c) | 135 (do-update-elc-2 dir compile-stage-p seen)))))) |
114 (while (setq file-c (car files)) | |
115 (setq files (cdr files)) | |
116 (setq file (replace-in-string file-c "c$" "")) | |
117 (when (and (file-exists-p file-c) | |
118 (not (file-exists-p file))) | |
119 (message "Removing %s; no corresponding .el" file-c) | |
120 (delete-file file-c))))) | |
121 | |
122 ;; We descend recursively | |
123 (let ((dirs (directory-files dir t nil t)) | |
124 dir) | |
125 (while (setq dir (pop dirs)) | |
126 (when (and (not (member (file-name-nondirectory dir) | |
127 update-elc-ignored-dirs)) | |
128 (file-directory-p dir)) | |
129 (do-update-elc-2 dir compile-stage-p seen)))) | |
130 | |
131 )) | |
132 | 136 |
133 (defun batch-update-elc-2 () | 137 (defun batch-update-elc-2 () |
134 (defvar command-line-args-left) | 138 (defvar command-line-args-left) |
135 (unless noninteractive | 139 (unless noninteractive |
136 (error "`batch-update-elc-2' is to be used only with -batch")) | 140 (error "`batch-update-elc-2' is to be used only with -batch")) |
137 (let ((dir (car command-line-args-left))) | 141 (let ((dir (car command-line-args-left))) |
142 ;; don't depend on being able to autoload `update-autoload-files'! | |
143 (load "autoload") | |
144 (load "bytecomp") | |
145 (load "byte-optimize") | |
146 ;; #### the API used here is deprecated, convert to one with explicit | |
147 ;; arguments when it is available | |
148 ;; update-elc.el signals us to rebuild the autoloads when necessary. | |
149 ;; in some cases it will rebuild the autoloads itself, but doing it this | |
150 ;; way is slow, so we avoid it when possible. | |
151 (when (file-exists-p "../src/REBUILD_AUTOLOADS") | |
152 (let ((generated-autoload-file (expand-file-name "auto-autoloads.el" dir)) | |
153 (autoload-package-name "auto")) ; feature prefix | |
154 (update-autoload-files (list dir)) | |
155 (byte-recompile-file generated-autoload-file 0)) | |
156 (when (featurep 'mule) | |
157 (let* ((muledir (expand-file-name "../lisp/mule" (file-truename dir))) | |
158 (generated-autoload-file | |
159 (expand-file-name "auto-autoloads.el" muledir)) | |
160 (autoload-package-name "mule")) ; feature prefix | |
161 (update-autoload-files (list muledir)) | |
162 (byte-recompile-file generated-autoload-file 0)))) | |
163 (when (featurep 'modules) | |
164 (let* ((moddir (expand-file-name "../modules" (file-truename dir))) | |
165 (generated-autoload-file | |
166 (expand-file-name "auto-autoloads.el" moddir)) | |
167 (autoload-package-name "modules")) ; feature prefix | |
168 (update-autoload-files | |
169 (delete (concat (file-name-as-directory moddir) ".") | |
170 (delete (concat (file-name-as-directory moddir) "..") | |
171 (directory-files moddir t nil nil 0))) | |
172 t) | |
173 (byte-recompile-file generated-autoload-file 0))) | |
174 ;; now load the (perhaps newly rebuilt) autoloads; we were called with | |
175 ;; -no-autoloads so they're not already loaded. | |
176 (load "../lisp/auto-autoloads") | |
177 (when (featurep 'mule) | |
178 (load "../lisp/mule/auto-autoloads")) | |
138 ;; We remove all the bad .elcs before any byte-compilation, because | 179 ;; We remove all the bad .elcs before any byte-compilation, because |
139 ;; there may be dependencies between one .el and another (even across | 180 ;; there may be dependencies between one .el and another (even across |
140 ;; directories), and we don't want to load an out-of-date .elc while | 181 ;; directories), and we don't want to load an out-of-date .elc while |
141 ;; byte-compiling a file. | 182 ;; byte-compiling a file. |
142 (message "Removing old or spurious .elcs in directory tree `%s'..." dir) | 183 (message "Removing old or spurious .elcs in directory tree `%s'..." dir) |
144 (message "Removing old or spurious .elcs in directory tree `%s'...done" | 185 (message "Removing old or spurious .elcs in directory tree `%s'...done" |
145 dir) | 186 dir) |
146 (message "Recompiling updated .els in directory tree `%s'..." dir) | 187 (message "Recompiling updated .els in directory tree `%s'..." dir) |
147 (do-update-elc-2 dir t nil) | 188 (do-update-elc-2 dir t nil) |
148 (message "Recompiling updated .els in directory tree `%s'...done" dir) | 189 (message "Recompiling updated .els in directory tree `%s'...done" dir) |
149 ;; don't depend on being able to autoload `update-autoload-files'! | |
150 (load "autoload") | |
151 ;; #### the API used here is deprecated, convert to one with explicit | |
152 ;; arguments when it is available | |
153 (let ((generated-autoload-file (expand-file-name "auto-autoloads.el" dir)) | |
154 (autoload-package-name "auto")) ; feature prefix | |
155 (update-autoload-files (list dir)) | |
156 (byte-recompile-file generated-autoload-file 0)) | |
157 (when (featurep 'modules) | |
158 (let* ((moddir (expand-file-name "../modules" (file-truename dir))) | |
159 (generated-autoload-file | |
160 (expand-file-name "auto-autoloads.el" moddir)) | |
161 (autoload-package-name "modules")) ; feature prefix | |
162 (update-autoload-files | |
163 (delete (concat (file-name-as-directory moddir) ".") | |
164 (delete (concat (file-name-as-directory moddir) "..") | |
165 (directory-files moddir t nil nil 0))) | |
166 t) | |
167 (byte-recompile-file generated-autoload-file 0))) | |
168 (when (featurep 'mule) | |
169 (let* ((muledir (expand-file-name "../lisp/mule" (file-truename dir))) | |
170 (generated-autoload-file | |
171 (expand-file-name "auto-autoloads.el" muledir)) | |
172 (autoload-package-name "mule")) ; feature prefix | |
173 (update-autoload-files (list muledir)) | |
174 (byte-recompile-file generated-autoload-file 0))) | |
175 ;; likewise here. | 190 ;; likewise here. |
176 (load "cus-dep") | 191 (load "cus-dep") |
177 (Custom-make-dependencies dir) | 192 (Custom-make-dependencies dir) |
178 (byte-recompile-file (expand-file-name "custom-load.el" dir) 0) | 193 (byte-recompile-file (expand-file-name "custom-load.el" dir) 0) |
179 (when (featurep 'mule) | 194 (when (featurep 'mule) |