aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordickmao2021-11-07 01:28:47 +0100
committerLars Ingebrigtsen2021-11-07 01:28:47 +0100
commit9dfd945a2c2055b1af869a685eb2a667daf4daca (patch)
treeccfe862dca7223dafd9921c5743686f623c0e41b
parent55fa6a2655972017c692b515b8c476bb9705747d (diff)
downloademacs-9dfd945a2c2055b1af869a685eb2a667daf4daca.tar.gz
emacs-9dfd945a2c2055b1af869a685eb2a667daf4daca.zip
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).
-rw-r--r--lisp/emacs-lisp/package.el120
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin-aux.el12
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin.el21
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin-aux.el16
-rw-r--r--test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin.el30
-rw-r--r--test/lisp/emacs-lisp/package-tests.el32
6 files changed, 151 insertions, 80 deletions
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index fcbcdc79d8e..4761a3d82ba 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -758,47 +758,47 @@ PKG-DESC is a `package-desc' object."
758 (format "%s-autoloads" (package-desc-name pkg-desc)) 758 (format "%s-autoloads" (package-desc-name pkg-desc))
759 (package-desc-dir pkg-desc))) 759 (package-desc-dir pkg-desc)))
760 760
761(defun package--activate-autoloads-and-load-path (pkg-desc)
762 "Load the autoloads file and add package dir to `load-path'.
763PKG-DESC is a `package-desc' object."
764 (let* ((old-lp load-path)
765 (pkg-dir (package-desc-dir pkg-desc))
766 (pkg-dir-dir (file-name-as-directory pkg-dir)))
767 (with-demoted-errors "Error loading autoloads: %s"
768 (load (package--autoloads-file-name pkg-desc) nil t))
769 (when (and (eq old-lp load-path)
770 (not (or (member pkg-dir load-path)
771 (member pkg-dir-dir load-path))))
772 ;; Old packages don't add themselves to the `load-path', so we have to
773 ;; do it ourselves.
774 (push pkg-dir load-path))))
775
776(defvar Info-directory-list) 761(defvar Info-directory-list)
777(declare-function info-initialize "info" ()) 762(declare-function info-initialize "info" ())
778 763
779(defvar package--quickstart-pkgs t 764(defvar package--quickstart-pkgs t
780 "If set to a list, we're computing the set of pkgs to activate.") 765 "If set to a list, we're computing the set of pkgs to activate.")
781 766
782(defun package--load-files-for-activation (pkg-desc reload) 767(defsubst package--library-stem (file)
783 "Load files for activating a package given by PKG-DESC. 768 (catch 'done
784Load the autoloads file, and ensure `load-path' is setup. If 769 (let (result)
785RELOAD is non-nil, also load all files in the package that 770 (dolist (suffix (get-load-suffixes) file)
786correspond to previously loaded files." 771 (setq result (string-trim file nil suffix))
787 (let* ((loaded-files-list 772 (unless (equal file result)
788 (when reload 773 (throw 'done result))))))
789 (package--list-loaded-files (package-desc-dir pkg-desc))))) 774
790 ;; Add to load path, add autoloads, and activate the package. 775(defun package--reload-previously-loaded (pkg-desc)
791 (package--activate-autoloads-and-load-path pkg-desc) 776 "Force reimportation of files in PKG-DESC already present in `load-history'.
792 ;; Call `load' on all files in `package-desc-dir' already present in 777New editions of files contain macro definitions and
793 ;; `load-history'. This is done so that macros in these files are updated 778redefinitions, the overlooking of which would cause
794 ;; to their new definitions. If another package is being installed which 779byte-compilation of the new package to fail."
795 ;; depends on this new definition, not doing this update would cause 780 (with-demoted-errors "Error in package--load-files-for-activation: %s"
796 ;; compilation errors and break the installation. 781 (let* (result
797 (with-demoted-errors "Error in package--load-files-for-activation: %s" 782 (dir (package-desc-dir pkg-desc))
798 (mapc (lambda (feature) (load feature nil t)) 783 (load-path-sans-dir
799 ;; Skip autoloads file since we already evaluated it above. 784 (cl-remove-if (apply-partially #'string= dir)
800 (remove (file-truename (package--autoloads-file-name pkg-desc)) 785 (or (bound-and-true-p find-function-source-path)
801 loaded-files-list))))) 786 load-path)))
787 (files (directory-files-recursively dir "\\`[^\\.].*\\.el\\'"))
788 (history (mapcar #'file-truename
789 (cl-remove-if-not #'stringp
790 (mapcar #'car load-history)))))
791 (dolist (file files)
792 (when-let ((library (package--library-stem
793 (file-relative-name file dir)))
794 (canonical (locate-library library nil load-path-sans-dir))
795 (found (member (file-truename canonical) history))
796 (recent-index (length found)))
797 (unless (equal (file-name-base library)
798 (format "%s-autoloads" (package-desc-name pkg-desc)))
799 (push (cons (expand-file-name library dir) recent-index) result))))
800 (mapc (lambda (c) (load (car c) nil t))
801 (sort result (lambda (x y) (< (cdr x) (cdr y))))))))
802 802
803(defun package-activate-1 (pkg-desc &optional reload deps) 803(defun package-activate-1 (pkg-desc &optional reload deps)
804 "Activate package given by PKG-DESC, even if it was already active. 804 "Activate package given by PKG-DESC, even if it was already active.
@@ -825,7 +825,11 @@ correspond to previously loaded files (those returned by
825 (if (listp package--quickstart-pkgs) 825 (if (listp package--quickstart-pkgs)
826 ;; We're only collecting the set of packages to activate! 826 ;; We're only collecting the set of packages to activate!
827 (push pkg-desc package--quickstart-pkgs) 827 (push pkg-desc package--quickstart-pkgs)
828 (package--load-files-for-activation pkg-desc reload)) 828 (when reload
829 (package--reload-previously-loaded pkg-desc))
830 (with-demoted-errors "Error loading autoloads: %s"
831 (load (package--autoloads-file-name pkg-desc) nil t))
832 (add-to-list 'load-path (directory-file-name pkg-dir)))
829 ;; Add info node. 833 ;; Add info node.
830 (when (file-exists-p (expand-file-name "dir" pkg-dir)) 834 (when (file-exists-p (expand-file-name "dir" pkg-dir))
831 ;; FIXME: not the friendliest, but simple. 835 ;; FIXME: not the friendliest, but simple.
@@ -836,48 +840,6 @@ correspond to previously loaded files (those returned by
836 ;; Don't return nil. 840 ;; Don't return nil.
837 t))) 841 t)))
838 842
839(defun package--files-load-history ()
840 (delq nil
841 (mapcar (lambda (x)
842 (let ((f (car x)))
843 (and (stringp f)
844 (file-name-sans-extension (file-truename f)))))
845 load-history)))
846
847(defun package--list-of-conflicts (dir history)
848 (require 'find-func)
849 (declare-function find-library-name "find-func" (library))
850 (delq
851 nil
852 (mapcar
853 (lambda (x) (let* ((file (file-relative-name x dir))
854 ;; Previously loaded file, if any.
855 (previous
856 (ignore-error file-error ;"Can't find library"
857 (file-name-sans-extension
858 (file-truename (find-library-name file)))))
859 (pos (when previous (member previous history))))
860 ;; Return (RELATIVE-FILENAME . HISTORY-POSITION)
861 (when pos
862 (cons (file-name-sans-extension file) (length pos)))))
863 (directory-files-recursively dir "\\`[^\\.].*\\.el\\'"))))
864
865(defun package--list-loaded-files (dir)
866 "Recursively list all files in DIR which correspond to loaded features.
867Returns the `file-name-sans-extension' of each file, relative to
868DIR, sorted by most recently loaded last."
869 (let* ((history (package--files-load-history))
870 (dir (file-truename dir))
871 ;; List all files that have already been loaded.
872 (list-of-conflicts (package--list-of-conflicts dir history)))
873 ;; Turn the list of (FILENAME . POS) back into a list of features. Files in
874 ;; subdirectories are returned relative to DIR (so not actually features).
875 (let ((default-directory (file-name-as-directory dir)))
876 (mapcar (lambda (x) (file-truename (car x)))
877 (sort list-of-conflicts
878 ;; Sort the files by ascending HISTORY-POSITION.
879 (lambda (x y) (< (cdr x) (cdr y))))))))
880
881;;;; `package-activate' 843;;;; `package-activate'
882 844
883(defun package--get-activatable-pkg (pkg-name) 845(defun package--get-activatable-pkg (pkg-name)
@@ -996,7 +958,7 @@ untar into a directory named DIR; otherwise, signal an error."
996 (package--native-compile-async new-desc)) 958 (package--native-compile-async new-desc))
997 ;; After compilation, load again any files loaded by 959 ;; After compilation, load again any files loaded by
998 ;; `activate-1', so that we use the byte-compiled definitions. 960 ;; `activate-1', so that we use the byte-compiled definitions.
999 (package--load-files-for-activation new-desc :reload))) 961 (package--reload-previously-loaded new-desc)))
1000 pkg-dir)) 962 pkg-dir))
1001 963
1002(defun package-generate-description-file (pkg-desc pkg-file) 964(defun package-generate-description-file (pkg-desc pkg-file)
diff --git a/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin-aux.el b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin-aux.el
new file mode 100644
index 00000000000..724f88ec9ea
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin-aux.el
@@ -0,0 +1,12 @@
1;;; macro-builtin-aux.el --- laksd -*- lexical-binding: t; -*-
2
3;; Author: Artur Malabarba <emacs@endlessparentheses.com>
4
5;;; Code:
6
7(defun macro-builtin-aux-1 ( &rest forms)
8 "Description"
9 `(progn ,@forms))
10
11(provide 'macro-builtin-aux)
12;;; macro-builtin-aux.el ends here
diff --git a/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin.el b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin.el
new file mode 100644
index 00000000000..828968a0576
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-1.0/macro-builtin.el
@@ -0,0 +1,21 @@
1;;; macro-builtin.el --- laksd -*- lexical-binding: t; -*-
2
3;; Author: Artur Malabarba <emacs@endlessparentheses.com>
4;; Keywords: tools
5;; Version: 1.0
6
7;;; Code:
8
9(require 'macro-builtin-aux)
10
11(defmacro macro-builtin-1 ( &rest forms)
12 "Description"
13 `(progn ,@forms))
14
15(defun macro-builtin-func ()
16 ""
17 (macro-builtin-1 'a 'b)
18 (macro-builtin-aux-1 'a 'b))
19
20(provide 'macro-builtin)
21;;; macro-builtin.el ends here
diff --git a/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin-aux.el b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin-aux.el
new file mode 100644
index 00000000000..9f257d9d22c
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin-aux.el
@@ -0,0 +1,16 @@
1;;; macro-builtin-aux.el --- laksd -*- lexical-binding: t; -*-
2
3;; Author: Artur Malabarba <emacs@endlessparentheses.com>
4
5;;; Code:
6
7(defmacro macro-builtin-aux-1 ( &rest forms)
8 "Description"
9 `(progn ,@forms))
10
11(defmacro macro-builtin-aux-3 ( &rest _)
12 "Description"
13 90)
14
15(provide 'macro-builtin-aux)
16;;; macro-builtin-aux.el ends here
diff --git a/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin.el b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin.el
new file mode 100644
index 00000000000..5d241c082d0
--- /dev/null
+++ b/test/lisp/emacs-lisp/package-resources/macro-builtin-package-2.0/macro-builtin.el
@@ -0,0 +1,30 @@
1;;; macro-builtin.el --- laksd -*- lexical-binding: t; -*-
2
3;; Author: Artur Malabarba <emacs@endlessparentheses.com>
4;; Keywords: tools
5;; Version: 2.0
6
7;;; Code:
8
9(require 'macro-builtin-aux)
10
11(defmacro macro-builtin-1 ( &rest forms)
12 "Description"
13 `(progn ,(cadr (car forms))))
14
15
16(defun macro-builtin-func ()
17 ""
18 (list (macro-builtin-1 '1 'b)
19 (macro-builtin-aux-1 'a 'b)))
20
21(defmacro macro-builtin-3 (&rest _)
22 "Description"
23 10)
24
25(defun macro-builtin-10-and-90 ()
26 ""
27 (list (macro-builtin-3 haha) (macro-builtin-aux-3 hehe)))
28
29(provide 'macro-builtin)
30;;; macro-builtin.el ends here
diff --git a/test/lisp/emacs-lisp/package-tests.el b/test/lisp/emacs-lisp/package-tests.el
index 1fd93bc1be7..c038c91e6a9 100644
--- a/test/lisp/emacs-lisp/package-tests.el
+++ b/test/lisp/emacs-lisp/package-tests.el
@@ -342,9 +342,13 @@ but with a different end of line convention (bug#48137)."
342 342
343(declare-function macro-problem-func "macro-problem" ()) 343(declare-function macro-problem-func "macro-problem" ())
344(declare-function macro-problem-10-and-90 "macro-problem" ()) 344(declare-function macro-problem-10-and-90 "macro-problem" ())
345(declare-function macro-builtin-func "macro-builtin" ())
346(declare-function macro-builtin-10-and-90 "macro-builtin" ())
345 347
346(ert-deftest package-test-macro-compilation () 348(ert-deftest package-test-macro-compilation ()
347 "Install a package which includes a dependency." 349 "\"Activation has to be done before compilation, so that if we're
350 upgrading and macros have changed we load the new definitions
351 before compiling.\" -- package.el"
348 (with-package-test (:basedir (ert-resource-directory)) 352 (with-package-test (:basedir (ert-resource-directory))
349 (package-install-file (expand-file-name "macro-problem-package-1.0/")) 353 (package-install-file (expand-file-name "macro-problem-package-1.0/"))
350 (require 'macro-problem) 354 (require 'macro-problem)
@@ -357,6 +361,32 @@ but with a different end of line convention (bug#48137)."
357 ;; `macro-problem-10-and-90' depends on an entirely new macro from `macro-aux'. 361 ;; `macro-problem-10-and-90' depends on an entirely new macro from `macro-aux'.
358 (should (equal (macro-problem-10-and-90) '(10 90))))) 362 (should (equal (macro-problem-10-and-90) '(10 90)))))
359 363
364(ert-deftest package-test-macro-compilation-gz ()
365 "Built-in's can be superseded as well."
366 (with-package-test (:basedir (ert-resource-directory))
367 (let ((dir (expand-file-name "macro-builtin-package-1.0")))
368 (unwind-protect
369 (let ((load-path load-path))
370 (add-to-list 'load-path (directory-file-name dir))
371 (byte-recompile-directory dir 0 t)
372 (mapc (lambda (f) (rename-file f (concat f ".gz")))
373 (directory-files-recursively dir "\\`[^\\.].*\\.el\\'"))
374 (require 'macro-builtin)
375 (should (member (expand-file-name "macro-builtin-aux.elc" dir)
376 (mapcar #'car load-history)))
377 ;; `macro-builtin-func' uses a macro from `macro-aux'.
378 (should (equal (macro-builtin-func) '(progn a b)))
379 (package-install-file (expand-file-name "macro-builtin-package-2.0/"))
380 ;; After upgrading, `macro-builtin-func' depends on a new version
381 ;; of the macro from `macro-builtin-aux'.
382 (should (equal (macro-builtin-func) '(1 b)))
383 ;; `macro-builtin-10-and-90' depends on an entirely new macro from `macro-aux'.
384 (should (equal (macro-builtin-10-and-90) '(10 90))))
385 (mapc #'delete-file
386 (directory-files-recursively dir "\\`[^\\.].*\\.elc\\'"))
387 (mapc (lambda (f) (rename-file f (file-name-sans-extension f)))
388 (directory-files-recursively dir "\\`[^\\.].*\\.el.gz\\'"))))))
389
360(ert-deftest package-test-install-two-dependencies () 390(ert-deftest package-test-install-two-dependencies ()
361 "Install a package which includes a dependency." 391 "Install a package which includes a dependency."
362 (with-package-test () 392 (with-package-test ()