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)