Fix byte compilation of package built-ins
* lisp/emacs-lisp/package.el (package--activate-autoloads-and-load-path): (package--load-files-for-activation): Remove. (package--library-stem): New function, because file-name-sans-extension is insufficient. (package--reload-previously-loaded): New function. (package-activate-1): Reload directly. (package--files-load-history): (package--list-of-conflicts): (package--list-loaded-files): Remove (package-unpack): Adjust call. * test/lisp/emacs-lisp/package-tests.el (macro-builtin-func): Test. (macro-builtin-10-and-90): Test. (package-test-macro-compilation): Test. (package-test-macro-compilation-gz): Test (bug#49708).
This commit is contained in:
parent
55fa6a2655
commit
9dfd945a2c
6 changed files with 151 additions and 80 deletions
|
@ -758,47 +758,47 @@ PKG-DESC is a `package-desc' object."
|
|||
(format "%s-autoloads" (package-desc-name pkg-desc))
|
||||
(package-desc-dir pkg-desc)))
|
||||
|
||||
(defun package--activate-autoloads-and-load-path (pkg-desc)
|
||||
"Load the autoloads file and add package dir to `load-path'.
|
||||
PKG-DESC is a `package-desc' object."
|
||||
(let* ((old-lp load-path)
|
||||
(pkg-dir (package-desc-dir pkg-desc))
|
||||
(pkg-dir-dir (file-name-as-directory pkg-dir)))
|
||||
(with-demoted-errors "Error loading autoloads: %s"
|
||||
(load (package--autoloads-file-name pkg-desc) nil t))
|
||||
(when (and (eq old-lp load-path)
|
||||
(not (or (member pkg-dir load-path)
|
||||
(member pkg-dir-dir load-path))))
|
||||
;; Old packages don't add themselves to the `load-path', so we have to
|
||||
;; do it ourselves.
|
||||
(push pkg-dir load-path))))
|
||||
|
||||
(defvar Info-directory-list)
|
||||
(declare-function info-initialize "info" ())
|
||||
|
||||
(defvar package--quickstart-pkgs t
|
||||
"If set to a list, we're computing the set of pkgs to activate.")
|
||||
|
||||
(defun package--load-files-for-activation (pkg-desc reload)
|
||||
"Load files for activating a package given by PKG-DESC.
|
||||
Load the autoloads file, and ensure `load-path' is setup. If
|
||||
RELOAD is non-nil, also load all files in the package that
|
||||
correspond to previously loaded files."
|
||||
(let* ((loaded-files-list
|
||||
(when reload
|
||||
(package--list-loaded-files (package-desc-dir pkg-desc)))))
|
||||
;; Add to load path, add autoloads, and activate the package.
|
||||
(package--activate-autoloads-and-load-path pkg-desc)
|
||||
;; Call `load' on all files in `package-desc-dir' already present in
|
||||
;; `load-history'. This is done so that macros in these files are updated
|
||||
;; to their new definitions. If another package is being installed which
|
||||
;; depends on this new definition, not doing this update would cause
|
||||
;; compilation errors and break the installation.
|
||||
(with-demoted-errors "Error in package--load-files-for-activation: %s"
|
||||
(mapc (lambda (feature) (load feature nil t))
|
||||
;; Skip autoloads file since we already evaluated it above.
|
||||
(remove (file-truename (package--autoloads-file-name pkg-desc))
|
||||
loaded-files-list)))))
|
||||
(defsubst package--library-stem (file)
|
||||
(catch 'done
|
||||
(let (result)
|
||||
(dolist (suffix (get-load-suffixes) file)
|
||||
(setq result (string-trim file nil suffix))
|
||||
(unless (equal file result)
|
||||
(throw 'done result))))))
|
||||
|
||||
(defun package--reload-previously-loaded (pkg-desc)
|
||||
"Force reimportation of files in PKG-DESC already present in `load-history'.
|
||||
New editions of files contain macro definitions and
|
||||
redefinitions, the overlooking of which would cause
|
||||
byte-compilation of the new package to fail."
|
||||
(with-demoted-errors "Error in package--load-files-for-activation: %s"
|
||||
(let* (result
|
||||
(dir (package-desc-dir pkg-desc))
|
||||
(load-path-sans-dir
|
||||
(cl-remove-if (apply-partially #'string= dir)
|
||||
(or (bound-and-true-p find-function-source-path)
|
||||
load-path)))
|
||||
(files (directory-files-recursively dir "\\`[^\\.].*\\.el\\'"))
|
||||
(history (mapcar #'file-truename
|
||||
(cl-remove-if-not #'stringp
|
||||
(mapcar #'car load-history)))))
|
||||
(dolist (file files)
|
||||
(when-let ((library (package--library-stem
|
||||
(file-relative-name file dir)))
|
||||
(canonical (locate-library library nil load-path-sans-dir))
|
||||
(found (member (file-truename canonical) history))
|
||||
(recent-index (length found)))
|
||||
(unless (equal (file-name-base library)
|
||||
(format "%s-autoloads" (package-desc-name pkg-desc)))
|
||||
(push (cons (expand-file-name library dir) recent-index) result))))
|
||||
(mapc (lambda (c) (load (car c) nil t))
|
||||
(sort result (lambda (x y) (< (cdr x) (cdr y))))))))
|
||||
|
||||
(defun package-activate-1 (pkg-desc &optional reload deps)
|
||||
"Activate package given by PKG-DESC, even if it was already active.
|
||||
|
@ -825,7 +825,11 @@ correspond to previously loaded files (those returned by
|
|||
(if (listp package--quickstart-pkgs)
|
||||
;; We're only collecting the set of packages to activate!
|
||||
(push pkg-desc package--quickstart-pkgs)
|
||||
(package--load-files-for-activation pkg-desc reload))
|
||||
(when reload
|
||||
(package--reload-previously-loaded pkg-desc))
|
||||
(with-demoted-errors "Error loading autoloads: %s"
|
||||
(load (package--autoloads-file-name pkg-desc) nil t))
|
||||
(add-to-list 'load-path (directory-file-name pkg-dir)))
|
||||
;; Add info node.
|
||||
(when (file-exists-p (expand-file-name "dir" pkg-dir))
|
||||
;; FIXME: not the friendliest, but simple.
|
||||
|
@ -836,48 +840,6 @@ correspond to previously loaded files (those returned by
|
|||
;; Don't return nil.
|
||||
t)))
|
||||
|
||||
(defun package--files-load-history ()
|
||||
(delq nil
|
||||
(mapcar (lambda (x)
|
||||
(let ((f (car x)))
|
||||
(and (stringp f)
|
||||
(file-name-sans-extension (file-truename f)))))
|
||||
load-history)))
|
||||
|
||||
(defun package--list-of-conflicts (dir history)
|
||||
(require 'find-func)
|
||||
(declare-function find-library-name "find-func" (library))
|
||||
(delq
|
||||
nil
|
||||
(mapcar
|
||||
(lambda (x) (let* ((file (file-relative-name x dir))
|
||||
;; Previously loaded file, if any.
|
||||
(previous
|
||||
(ignore-error file-error ;"Can't find library"
|
||||
(file-name-sans-extension
|
||||
(file-truename (find-library-name file)))))
|
||||
(pos (when previous (member previous history))))
|
||||
;; Return (RELATIVE-FILENAME . HISTORY-POSITION)
|
||||
(when pos
|
||||
(cons (file-name-sans-extension file) (length pos)))))
|
||||
(directory-files-recursively dir "\\`[^\\.].*\\.el\\'"))))
|
||||
|
||||
(defun package--list-loaded-files (dir)
|
||||
"Recursively list all files in DIR which correspond to loaded features.
|
||||
Returns the `file-name-sans-extension' of each file, relative to
|
||||
DIR, sorted by most recently loaded last."
|
||||
(let* ((history (package--files-load-history))
|
||||
(dir (file-truename dir))
|
||||
;; List all files that have already been loaded.
|
||||
(list-of-conflicts (package--list-of-conflicts dir history)))
|
||||
;; Turn the list of (FILENAME . POS) back into a list of features. Files in
|
||||
;; subdirectories are returned relative to DIR (so not actually features).
|
||||
(let ((default-directory (file-name-as-directory dir)))
|
||||
(mapcar (lambda (x) (file-truename (car x)))
|
||||
(sort list-of-conflicts
|
||||
;; Sort the files by ascending HISTORY-POSITION.
|
||||
(lambda (x y) (< (cdr x) (cdr y))))))))
|
||||
|
||||
;;;; `package-activate'
|
||||
|
||||
(defun package--get-activatable-pkg (pkg-name)
|
||||
|
@ -996,7 +958,7 @@ untar into a directory named DIR; otherwise, signal an error."
|
|||
(package--native-compile-async new-desc))
|
||||
;; After compilation, load again any files loaded by
|
||||
;; `activate-1', so that we use the byte-compiled definitions.
|
||||
(package--load-files-for-activation new-desc :reload)))
|
||||
(package--reload-previously-loaded new-desc)))
|
||||
pkg-dir))
|
||||
|
||||
(defun package-generate-description-file (pkg-desc pkg-file)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue