aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/package/package-compile.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/package/package-compile.el')
-rw-r--r--lisp/package/package-compile.el111
1 files changed, 111 insertions, 0 deletions
diff --git a/lisp/package/package-compile.el b/lisp/package/package-compile.el
new file mode 100644
index 00000000000..ffe94880efd
--- /dev/null
+++ b/lisp/package/package-compile.el
@@ -0,0 +1,111 @@
1;;; package-compile.el --- Byte-Compilation of Packages -*- lexical-binding: t; -*-
2
3;; Copyright (C) 2025 Philip Kaludercic
4
5;; Author: Philip Kaludercic <philipk@posteo.net>
6
7;; This program is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation, either version 3 of the License, or
10;; (at your option) any later version.
11
12;; This program is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with this program. If not, see <https://www.gnu.org/licenses/>.
19
20;;; Commentary:
21
22;;; Code:
23
24(require 'package-core)
25
26(defvar warning-minimum-level)
27(defvar byte-compile-ignore-files)
28
29(defcustom package-native-compile nil
30 "Non-nil means to natively compile packages as part of their installation.
31This controls ahead-of-time compilation of packages when they are
32installed. If this option is nil, packages will be natively
33compiled when they are loaded for the first time.
34
35This option does not have any effect if Emacs was not built with
36native compilation support."
37 :type '(boolean)
38 :risky t
39 :version "28.1"
40 :group 'package)
41
42(defun package--parse-elpaignore (pkg-desc)
43 "Return a list of regular expressions to match files ignored by PKG-DESC."
44 (let* ((pkg-dir (file-name-as-directory (package-desc-dir pkg-desc)))
45 (ignore (expand-file-name ".elpaignore" pkg-dir))
46 files)
47 (when (file-exists-p ignore)
48 (with-temp-buffer
49 (insert-file-contents ignore)
50 (goto-char (point-min))
51 (while (not (eobp))
52 (push (wildcard-to-regexp
53 (let ((line (buffer-substring
54 (line-beginning-position)
55 (line-end-position))))
56 (file-name-concat pkg-dir (string-trim-left line "/"))))
57 files)
58 (forward-line)))
59 files)))
60
61(defun package--compile (pkg-desc)
62 "Byte-compile installed package PKG-DESC.
63This assumes that `pkg-desc' has already been activated with
64`package-activate-1'."
65 (let ((byte-compile-ignore-files (package--parse-elpaignore pkg-desc))
66 (warning-minimum-level :error)
67 (load-path load-path))
68 (byte-recompile-directory (package-desc-dir pkg-desc) 0 t)))
69
70(defun package--native-compile-async (pkg-desc)
71 "Native compile installed package PKG-DESC asynchronously.
72This assumes that `pkg-desc' has already been activated with
73`package-activate-1'."
74 (when (native-comp-available-p)
75 (let ((warning-minimum-level :error))
76 (native-compile-async (package-desc-dir pkg-desc) t))))
77
78
79
80;;;###autoload
81(defun package-recompile (pkg)
82 "Byte-compile package PKG again.
83PKG should be either a symbol, the package name, or a `package-desc'
84object."
85 (interactive (list (intern (completing-read
86 "Recompile package: "
87 (mapcar #'symbol-name
88 (mapcar #'car package-alist))))))
89 (let ((pkg-desc (if (package-desc-p pkg)
90 pkg
91 (cadr (assq pkg package-alist)))))
92 ;; Delete the old .elc files to ensure that we don't inadvertently
93 ;; load them (in case they contain byte code/macros that are now
94 ;; invalid).
95 (dolist (elc (directory-files-recursively
96 (package-desc-dir pkg-desc) "\\.elc\\'"))
97 (delete-file elc))
98 (package--compile pkg-desc)))
99
100;;;###autoload
101(defun package-recompile-all ()
102 "Byte-compile all installed packages.
103This is meant to be used only in the case the byte-compiled files
104are invalid due to changed byte-code, macros or the like."
105 (interactive)
106 (pcase-dolist (`(_ ,pkg-desc) package-alist)
107 (with-demoted-errors "Error while recompiling: %S"
108 (package-recompile pkg-desc))))
109
110(provide 'package-compile)
111;;; package-compile.el ends here