diff --git a/Makefile.am b/Makefile.am index 16bcb667a4..1c5688ac13 100644 --- a/Makefile.am +++ b/Makefile.am @@ -422,6 +422,7 @@ dist_noinst_DATA = \ # Auxiliary files for packages. AUX_FILES = \ gnu/packages/aux-files/chromium/master-preferences.json \ + gnu/packages/aux-files/emacs/comp-integrity.el \ gnu/packages/aux-files/emacs/guix-emacs.el \ gnu/packages/aux-files/findclass.php \ gnu/packages/aux-files/guix.vim \ diff --git a/gnu/local.mk b/gnu/local.mk index e4ff3817dc..8ed40d3225 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -1134,6 +1134,7 @@ dist_patch_DATA = \ %D%/packages/patches/emacs-all-the-icons-remove-duplicate-rs.patch \ %D%/packages/patches/emacs-deferred-fix-number-of-arguments.patch \ %D%/packages/patches/emacs-elpy-dup-test-name.patch \ + %D%/packages/patches/emacs-disable-jit-compilation.patch \ %D%/packages/patches/emacs-exec-path.patch \ %D%/packages/patches/emacs-fix-scheme-indent-function.patch \ %D%/packages/patches/emacs-git-email-missing-parens.patch \ @@ -1143,6 +1144,7 @@ dist_patch_DATA = \ %D%/packages/patches/emacs-kv-fix-tests.patch \ %D%/packages/patches/emacs-lispy-fix-thread-last-test.patch \ %D%/packages/patches/emacs-native-comp-driver-options.patch \ + %D%/packages/patches/emacs-native-comp-fix-filenames.patch \ %D%/packages/patches/emacs-next-exec-path.patch \ %D%/packages/patches/emacs-next-native-comp-driver-options.patch \ %D%/packages/patches/emacs-pasp-mode-quote-file-names.patch \ diff --git a/gnu/packages/aux-files/emacs/comp-integrity.el b/gnu/packages/aux-files/emacs/comp-integrity.el new file mode 100644 index 0000000000..abe7e7c0c9 --- /dev/null +++ b/gnu/packages/aux-files/emacs/comp-integrity.el @@ -0,0 +1,132 @@ +(require 'ert) + +(eval-when-compile + (require 'help-fns) + + (defmacro expect-help (fun result &optional feature) + `(progn + (eval-when-compile (when ',feature + (require ',feature))) + + (ert-deftest ,(intern (concat "expect-" (symbol-name fun) + "-" (symbol-name result))) + () + (should + (eq ',result + (let ((desc (substring-no-properties + (with-output-to-string + (help-fns-function-description-header ',fun))))) + (cond ((string-search "native-compiled" desc) 'native) + ((string-search "byte-compiled" desc) 'byte) + ((string-search "built-in" desc) 'built-in) + (t nil)))))))) + + (defmacro expect-native (fun &optional feature) + `(progn (expect-help ,fun native ,feature))) + + (defmacro expect-native-if-bound (fun) + `(and (boundp ',fun) (expect-help ,fun native))) + + (defmacro expect-builtin (fun &optional feature) + `(progn (expect-help ,fun built-in ,feature)))) + +(expect-native abbrev-mode) +(expect-native backquote-process) +(expect-native mode-line-widen) +(expect-native buffer-menu) +(expect-native button-mode) +(expect-native byte-run-strip-symbol-positions) +(expect-native case-table-get-table) +(expect-native cconv-convert) +(expect-native use-default-char-width-table) +(expect-native cl-generic-p) +(expect-native cl-struct-define) +(expect-native-if-bound x-setup-function-keys) +(expect-native encode-composition-rule) +(expect-native custom-declare-face) +(expect-native minibuffer-prompt-properties--setter) +(expect-native custom-add-choice) +(expect-native debug-early) +(expect-native display-table-slot disp-table) +(expect-native dnd-open-file) +(expect-native dos-mode25 dos-fns) +(expect-native find-file-text dos-w32) +(expect-native-if-bound dynamic-setting-handle-config-changed-event) +(expect-native easy-menu-item-present-p) +(expect-native eldoc-mode) +(expect-native electric-indent-mode) +(expect-native elisp-mode-syntax-propertize) +(expect-native getenv) +(expect-native epa-file-find-file-hook) +(expect-native face-list) +(expect-native find-file-noselect) +(expect-native fill-region) +(expect-native font-lock-change-mode) +(expect-native font-lock-add-keywords) +(expect-native-if-bound fontset-plain-name) +(expect-native format-read) +(expect-native frame-edges) +(expect-native-if-bound fringe-mode) +(expect-native help-quick) +(expect-native-if-bound image-type) +(expect-native indent-region) +(expect-native indian-compose-regexp) +(expect-native msdos-setup-keyboard term/internal) +(expect-native isearch-abort) +(expect-native iso-transl-set-language) +(expect-native jit-lock-mode) +(expect-native jka-compr-build-file-regexp) +(expect-native keymap-global-set) +(expect-native forward-sexp) +(expect-native lisp-string-in-doc-position-p) +(expect-native ls-lisp-set-options ls-lisp) +(expect-native macroexp-compiling-p) +(expect-native map-y-or-n-p) +(expect-native menu-find-file-existing) +(expect-native completion-boundaries) +(expect-native egyptian-shape-grouping) +(expect-native mouse-double-click-time) +(expect-native convert-define-charset-argument) +(expect-native coding-system-change-eol-conversion) +(expect-native store-substring mule-util) +(expect-native-if-bound mouse-wheel-change-button) +(expect-native advice-function-mapc) +(expect-native comment-string-strip) +(if (>= emacs-major-version 30) + (expect-builtin obarray-make) + (expect-native obarray-make)) +(expect-native obarray-map) +(expect-native oclosure-type) +(expect-native forward-page) +(expect-native sentence-end) +(expect-native show-paren-function) +(expect-native pgtk-dnd-init-frame pgtk-dnd) +(expect-native prog-context-menu) +(expect-native-if-bound regexp-opt) +(expect-native get-register) +(expect-native query-replace-descr) +(expect-native rfn-eshadow-setup-minibuffer) +(expect-native read-multiple-choice) +(expect-native-if-bound scroll-bar-scale) +(expect-native gui-select-text) +(expect-native seq-first) +(expect-native hack-read-symbol-shorthands) +(expect-native next-error-find-buffer) +(expect-native exit-splash-screen) +(expect-native buffer-local-boundp) +(expect-native syntax-propertize-multiline) +(expect-native tab-bar-mode) +(expect-native tabulated-list-put-tag) +(expect-native text-mode) +(expect-native timer-activate) +(expect-native tool-bar-mode) +(expect-native tooltip-mode) +(expect-native tty-color-desc) +(expect-native ucs-normalize-hfs-nfd-comp-p ucs-normalize) +(expect-native uniquify-item-p) +(expect-native vc-mode) +(expect-native emacs-version) +(expect-native define-widget) +(expect-native window-right) +(expect-native x-dnd-init-frame x-dnd) +(expect-native-if-bound x-handle-no-bitmap-icon) diff --git a/gnu/packages/dictionaries.scm b/gnu/packages/dictionaries.scm index 06b5c4362c..9f493d91ad 100644 --- a/gnu/packages/dictionaries.scm +++ b/gnu/packages/dictionaries.scm @@ -272,12 +272,12 @@ and a Python library.") curl "/bin:" fribidi "/bin:" rlwrap "/bin"))))))) + (add-after 'unpack 'emacs-make-autoloads + (assoc-ref emacs:%standard-phases 'make-autoloads)) (add-after 'install 'emacs-install (assoc-ref emacs:%standard-phases 'install)) - (add-after 'emacs-install 'emacs-make-autoloads - (assoc-ref emacs:%standard-phases 'make-autoloads)) - (add-after 'emacs-make-autoloads 'emacs-autoloads-compilation - (assoc-ref emacs:%standard-phases 'enable-autoloads-compilation))) + (add-after 'emacs-install 'emacs-build + (assoc-ref emacs:%standard-phases 'build))) #:make-flags (list (string-append "PREFIX=" %output) "NETWORK_ACCESS=no test") #:imported-modules (,@%gnu-build-system-modules diff --git a/gnu/packages/emacs-xyz.scm b/gnu/packages/emacs-xyz.scm index 6f0819e694..975b26813a 100644 --- a/gnu/packages/emacs-xyz.scm +++ b/gnu/packages/emacs-xyz.scm @@ -599,8 +599,7 @@ API key.") (search-input-file inputs "bin/guile")))))) (add-after 'make-autoloads 'patch-autoloads (lambda _ - (substitute* (string-append (elpa-directory #$output) - "/geiser-guile-autoloads.el") + (substitute* "geiser-guile-autoloads.el" ;; Activating implementations fails when Geiser is not yet ;; loaded, so let's defer that until it is. (("\\(geiser-activate-implementation .*\\)" all) @@ -669,8 +668,7 @@ using geiser.") (search-input-file inputs "bin/gosh"))))) (add-after 'make-autoloads 'patch-autoloads (lambda _ - (substitute* (string-append (elpa-directory #$output) - "/geiser-gauche-autoloads.el") + (substitute* "geiser-gauche-autoloads.el" ;; Activating implementations fails when Geiser is not yet ;; loaded, so let's defer that until it is. (("\\(geiser-activate-implementation .*\\)" all) @@ -715,8 +713,7 @@ a generic Scheme interaction mode for the GNU Emacs editor.") (search-input-file inputs "bin/racket")))))) (add-after 'make-autoloads 'patch-autoloads (lambda _ - (substitute* (string-append (elpa-directory #$output) - "/geiser-racket-autoloads.el") + (substitute* "geiser-racket-autoloads.el" ;; Activating implementations fails when Geiser is not yet ;; loaded, so let's defer that until it is. (("\\(geiser-activate-implementation .*\\)" all) @@ -754,9 +751,7 @@ a generic Scheme interaction mode for the GNU Emacs editor.") (modify-phases %standard-phases (add-after 'make-autoloads 'patch-autoloads (lambda* (#:key outputs #:allow-other-keys) - (substitute* (string-append - (elpa-directory (assoc-ref outputs "out")) - "/geiser-chez-autoloads.el") + (substitute* "geiser-chez-autoloads.el" ;; Activating implementations fails when Geiser is not yet ;; loaded, so let's defer that until it is. ;; See . @@ -1593,13 +1588,11 @@ on stdout instead of using a socket as the Emacsclient does.") emacs:%default-include))))) (add-after 'unpack 'emacs-add-install-to-native-load-path (assoc-ref emacs:%standard-phases 'add-install-to-native-load-path)) - (add-after 'install 'make-autoloads + (add-after 'unpack 'make-autoloads (assoc-ref emacs:%standard-phases 'make-autoloads)) - (add-after 'make-autoloads 'enable-autoloads-compilation - (assoc-ref emacs:%standard-phases 'enable-autoloads-compilation)) - (add-after 'enable-autoloads-compilation 'patch-el-files + (add-after 'unpack 'patch-el-files (assoc-ref emacs:%standard-phases 'patch-el-files)) - (add-after 'patch-el-files 'emacs-build + (add-after 'install 'emacs-build (assoc-ref emacs:%standard-phases 'build)) (add-after 'emacs-build 'validate-compiled-autoloads (assoc-ref emacs:%standard-phases 'validate-compiled-autoloads))))) @@ -1678,7 +1671,11 @@ libgit2 bindings for Emacs, intended to boost the performance of Magit.") (replace 'install (lambda args (with-directory-excursion "lisp" - (apply (assoc-ref %standard-phases 'install) args))))))) + (apply (assoc-ref %standard-phases 'install) args)))) + (replace 'build + (lambda args + (with-directory-excursion "lisp" + (apply (assoc-ref %standard-phases 'build) args))))))) (native-inputs (list texinfo)) (inputs @@ -3933,6 +3930,8 @@ defined in RFC 2425 and RFC 2426 to/from The Insidious Big Brother Database (emacs-substitute-sexps "eweouz.el" ("eweouz-helper-dirs" `(list ,(string-append #$output "/libexec/eweouz")))))) + (add-after 'enter-lisp-dir 'emacs-make-autoloads + (assoc-ref emacs:%standard-phases 'make-autoloads)) (add-after 'emacs-patch-variables 'emacs-expand-load-path (assoc-ref emacs:%standard-phases 'expand-load-path)) (add-after 'emacs-expand-load-path 'emacs-add-install-to-native-load-path @@ -3940,9 +3939,7 @@ defined in RFC 2425 and RFC 2426 to/from The Insidious Big Brother Database (add-after 'emacs-add-install-to-native-load-path 'emacs-install (assoc-ref emacs:%standard-phases 'install)) (add-after 'emacs-install 'emacs-build - (assoc-ref emacs:%standard-phases 'build)) - (add-after 'emacs-install 'emacs-make-autoloads - (assoc-ref emacs:%standard-phases 'make-autoloads))))) + (assoc-ref emacs:%standard-phases 'build))))) (native-inputs (list autoconf automake @@ -5611,6 +5608,8 @@ during idle time, while Emacs is doing nothing else.") ;; upgrading" that pdf-tools tries to perform. (emacs-substitute-variables "pdf-tools.el" ("pdf-tools-handle-upgrades" '())))) + (add-after 'enter-lisp-dir 'emacs-make-autoloads + (assoc-ref emacs:%standard-phases 'make-autoloads)) (add-after 'emacs-patch-variables 'emacs-expand-load-path (assoc-ref emacs:%standard-phases 'expand-load-path)) (add-after 'emacs-expand-load-path 'emacs-add-install-to-native-load-path @@ -5618,9 +5617,7 @@ during idle time, while Emacs is doing nothing else.") (add-after 'emacs-add-install-to-native-load-path 'emacs-install (assoc-ref emacs:%standard-phases 'install)) (add-after 'emacs-install 'emacs-build - (assoc-ref emacs:%standard-phases 'build)) - (add-after 'emacs-install 'emacs-make-autoloads - (assoc-ref emacs:%standard-phases 'make-autoloads))))) + (assoc-ref emacs:%standard-phases 'build))))) (native-inputs (list autoconf automake emacs-minimal pkg-config)) (inputs @@ -16936,7 +16933,7 @@ passive voice.") (define-public emacs-org (package (name "emacs-org") - (version "9.6.21") + (version "9.6.24") (source (origin (method git-fetch) @@ -16945,7 +16942,7 @@ passive voice.") (commit (string-append "release_" version)))) (file-name (git-file-name name version)) (sha256 - (base32 "1hf76wa7qvp9lvkr3rgzk7q3slq7mf17w6w6axaj6cn73ryn2ldw")))) + (base32 "1ry7zqv25zbh2lvmirm8vyxc55zggf7s7508nkf4yfs4yayr7rnw")))) (build-system emacs-build-system) (arguments (list @@ -16987,6 +16984,10 @@ passive voice.") (substitute* "testing/lisp/test-org.el" (("test-org/org-(encode-time|time-string-to-time) .*" all) (string-append all " (skip-unless nil)\n"))))) + (replace 'build + (lambda args + (with-directory-excursion "lisp" + (apply (assoc-ref %standard-phases 'build) args)))) (replace 'install (lambda _ (let ((elpa (elpa-directory #$output)) diff --git a/gnu/packages/emacs.scm b/gnu/packages/emacs.scm index 26bbbc6c9f..a30e0b9b40 100644 --- a/gnu/packages/emacs.scm +++ b/gnu/packages/emacs.scm @@ -100,17 +100,19 @@ (define-public emacs-minimal (package (name "emacs-minimal") - (version "29.1") + (version "29.3") (source (origin (method url-fetch) (uri (string-append "mirror://gnu/emacs/emacs-" version ".tar.xz")) (sha256 (base32 - "009f7q08vg919b90k2jrsznq73s3n224avz80dd2y7i3rjjq3y6j")) - (patches (search-patches "emacs-exec-path.patch" + "1822swrk4ifmkd4h9l0h37zifcpa1w3sy3vsgyffsrp6mk9hak63")) + (patches (search-patches "emacs-disable-jit-compilation.patch" + "emacs-exec-path.patch" "emacs-fix-scheme-indent-function.patch" "emacs-native-comp-driver-options.patch" + "emacs-native-comp-fix-filenames.patch" "emacs-pgtk-super-key-fix.patch")) (modules '((guix build utils))) (snippet @@ -376,7 +378,25 @@ editor (console only)") (string-append "-B" #$(this-package-input "libgccjit") "/lib/") (string-append - "-B" #$(this-package-input "libgccjit") "/lib/gcc/")))))))))) + "-B" #$(this-package-input "libgccjit") "/lib/gcc/")))))) + (add-after 'build 'build-trampolines + (lambda* (#:key make-flags #:allow-other-keys) + (apply invoke "make" "trampolines" make-flags))) + (add-after 'validate-runpath 'validate-comp-integrity + (lambda* (#:key outputs #:allow-other-keys) + #$(cond + ((%current-target-system) + #~(display "Cannot validate native-comp on cross builds.\n")) + ((string=? (%current-system) "armhf-linux") + #~(display "Integrity test is broken on armhf.\n")) + (else + #~(invoke + (string-append (assoc-ref outputs "out") "/bin/emacs") + "--batch" + "--load" + #$(local-file + (search-auxiliary-file "emacs/comp-integrity.el")) + "-f" "ert-run-tests-batch-and-exit"))))))))) (inputs (modify-inputs (package-inputs emacs-minimal) (prepend gnutls @@ -533,8 +553,8 @@ editor (with wide ints)" ) #~(cons "--with-wide-int" #$flags)))))) (define-public emacs-next-minimal - (let ((commit "9d27b95b263473fb41a30e3f6ea5607c99e93a61") - (revision "1")) + (let ((commit "170c6557922dad7e6e9bc0d6dadf6c080108fd42") + (revision "2")) (package (inherit emacs-minimal) (name "emacs-next-minimal") @@ -547,7 +567,7 @@ editor (with wide ints)" ) (commit commit))) (file-name (git-file-name name version)) (sha256 - (base32 "00mwpq1msr3jij281w5piqmbwq968xr8dn9hqbf4r947ck754kn9")) + (base32 "04carva3b6h9fnlzazrsxsj41hcnjc26kxjij07l159azi40l6sk")) (patches (search-patches "emacs-next-exec-path.patch" "emacs-fix-scheme-indent-function.patch" diff --git a/gnu/packages/guile-xyz.scm b/gnu/packages/guile-xyz.scm index 49b8ee7e59..3d36b6a53c 100644 --- a/gnu/packages/guile-xyz.scm +++ b/gnu/packages/guile-xyz.scm @@ -2311,12 +2311,12 @@ user which package sets would they like to install from it.") (invoke "guild" "compile" "-L" module-dir file "-o" go))) (find-files module-dir "\\.scm$"))))) + (add-after 'unpack 'make-autoloads + (assoc-ref emacs:%standard-phases 'make-autoloads)) (add-after 'install 'install-emacs-files (assoc-ref emacs:%standard-phases 'install)) (add-after 'install-emacs-files 'compile-emacs-files - (assoc-ref emacs:%standard-phases 'build)) - (add-after 'compile-emacs-files 'make-autoloads - (assoc-ref emacs:%standard-phases 'make-autoloads))))) + (assoc-ref emacs:%standard-phases 'build))))) (home-page "https://www.draketo.de/english/wisp") (inputs (list guile-3.0)) diff --git a/gnu/packages/language.scm b/gnu/packages/language.scm index db78425ec9..0b562bcde9 100644 --- a/gnu/packages/language.scm +++ b/gnu/packages/language.scm @@ -1003,15 +1003,15 @@ and manipulation.") "convert2skk/skk2list") (find-files "filters" "\\.rb$")))))) ;; Install and make autoloads for skk-xml.el. + (add-after 'unpack 'make-autoloads + (assoc-ref emacs:%standard-phases + 'make-autoloads)) (add-after 'install 'install-emacs-files (assoc-ref emacs:%standard-phases 'install)) (add-after 'install-emacs-files 'compile-emacs-files (assoc-ref emacs:%standard-phases 'build)) - (add-after 'compile-emacs-files 'make-autoloads - (assoc-ref emacs:%standard-phases - 'make-autoloads)) (add-after 'install 'install-docs (lambda* (#:key outputs #:allow-other-keys) (let ((doc (string-append (assoc-ref outputs "out") diff --git a/gnu/packages/mail.scm b/gnu/packages/mail.scm index 96a1e3b199..e0fbd0a5ff 100644 --- a/gnu/packages/mail.scm +++ b/gnu/packages/mail.scm @@ -1171,17 +1171,17 @@ repository and Maildir/IMAP as LOCAL repository.") "0xazygwdc328m5l31rxjazq9giv2xrygp2p2q455lf3jhdxwq1km")))) (build-system gnu-build-system) (arguments - (let ((elisp-dir #~(string-append #$output "/share/emacs/site-lisp")) - (icon-dir #~(string-append #$output "/share/mew"))) + (let ((icon-dir #~(string-append #$output "/share/mew"))) (list #:modules '((guix build gnu-build-system) (guix build utils) + ((guix build emacs-build-system) #:prefix emacs:) (guix build emacs-utils)) - #:imported-modules `(,@%gnu-build-system-modules - (guix build emacs-utils)) + #:imported-modules %emacs-build-system-modules #:tests? #f #:configure-flags - #~(list (string-append "--with-elispdir=" #$elisp-dir) + #~(list (string-append "--with-elispdir=" + (emacs:elpa-directory #$output)) (string-append "--with-etcdir=" #$icon-dir)) #:phases #~(modify-phases %standard-phases @@ -1192,9 +1192,15 @@ repository and Maildir/IMAP as LOCAL repository.") `(progn (add-to-list 'image-load-path 'mew-icon-directory) ,#$icon-dir))))) - (add-after 'install 'generate-autoloads + (add-after 'unpack 'generate-autoloads (lambda _ - (emacs-generate-autoloads "mew" #$elisp-dir))))))) + (emacs-generate-autoloads "mew" "elisp") + (substitute* "elisp/mew-autoloads.el" + ((";; no-byte-compile.*") "")) + ;; Add generated autoloads to Makefile, so they get compiled + (substitute* "elisp/Makefile" + (("OBJS =") "OBJS = mew-autoloads.elc") + (("SRCS =") "SRCS = mew-autoloads.el")))))))) (native-inputs (list emacs)) (propagated-inputs @@ -4784,14 +4790,12 @@ ex-like commands on it.") (for-each (lambda (file) (install-file file (string-append out "/bin"))) (list "mailfilter.crm" "mailreaver.crm" "mailtrainer.crm"))))) + ;; Run phases from the emacs build system. + (add-after 'unpack 'make-autoloads + (assoc-ref emacs:%standard-phases 'make-autoloads)) (add-after 'install 'install-emacs-mode (assoc-ref emacs:%standard-phases 'install)) - ;; Run phases from the emacs build system. - (add-after 'install-emacs-mode 'make-autoloads - (assoc-ref emacs:%standard-phases 'make-autoloads)) - (add-after 'make-autoloads 'enable-autoloads-compilation - (assoc-ref emacs:%standard-phases 'enable-autoloads-compilation)) - (add-after 'enable-autoloads-compilation 'emacs-build + (add-after 'install-emacs-mode 'emacs-build (assoc-ref emacs:%standard-phases 'build)) (add-after 'emacs-build 'validate-compiled-autoloads (assoc-ref emacs:%standard-phases 'validate-compiled-autoloads))))) diff --git a/gnu/packages/patches/emacs-disable-jit-compilation.patch b/gnu/packages/patches/emacs-disable-jit-compilation.patch new file mode 100644 index 0000000000..8b1ac5a9df --- /dev/null +++ b/gnu/packages/patches/emacs-disable-jit-compilation.patch @@ -0,0 +1,19 @@ +Index: emacs-29.2/src/comp.c +=================================================================== +--- emacs-29.2.orig/src/comp.c ++++ emacs-29.2/src/comp.c +@@ -5648,8 +5648,12 @@ For internal use. */); + doc: /* If non-nil, compile loaded .elc files asynchronously. + + After compilation, each function definition is updated to use the +-natively-compiled one. */); +- native_comp_jit_compilation = true; ++natively-compiled one. This variable is enabled by default upstream, ++but disabled in Guix to better make use of precompiled packages. ++Notably, Guix removes the hashes that prevent inadvertent shadowing ++frm the file names of compiled libraries in order to facilitate grafts. ++Enable at your own risk! */); ++ native_comp_jit_compilation = false; + + DEFSYM (Qnative_comp_speed, "native-comp-speed"); + DEFSYM (Qnative_comp_debug, "native-comp-debug"); diff --git a/gnu/packages/patches/emacs-native-comp-fix-filenames.patch b/gnu/packages/patches/emacs-native-comp-fix-filenames.patch new file mode 100644 index 0000000000..169323f290 --- /dev/null +++ b/gnu/packages/patches/emacs-native-comp-fix-filenames.patch @@ -0,0 +1,338 @@ +Upstream hashes both the absolute file name and the content of a file +to derive the name for the natively compiled files. This breaks the +staged install used in guix, as any $GUIX_PROFILE is distinct from +the build directory. It also breaks grafts, as hardcoded store file +names get rewritten; thus changing the file hash. + +In addition, this patch changes how native-comp-eln-load-path is +constructed. Upstream, an entry of the directory “../lisp” is added +supposedly for bootstrap only, but this directory appears to find its +way into the actual variable despite attempts to remove it by calling +‘startup--update-eln-cache’. +The user-visible procedure ‘startup-redirect-eln-cache’ is kept, as +packages may require it, but only pushes the new value now. + +Index: emacs-29.2/src/comp.c +=================================================================== +--- emacs-29.2.orig/src/comp.c ++++ emacs-29.2/src/comp.c +@@ -4396,26 +4396,17 @@ DEFUN ("comp-el-to-eln-rel-filename", Fc + Scomp_el_to_eln_rel_filename, 1, 1, 0, + doc: /* Return the relative name of the .eln file for FILENAME. + FILENAME must exist, and if it's a symlink, the target must exist. +-If FILENAME is compressed, it must have the \".gz\" extension, +-and Emacs must have been compiled with zlib; the file will be +-uncompressed on the fly to hash its contents. +-Value includes the original base name, followed by 2 hash values, +-one for the file name and another for its contents, followed by .eln. */) ++FILENAME is resolved relative to `load-path' and only the suffix of ++the first matching path is kept. If FILENAME is not found to be relative ++to any directory `load-path', it is used as-is to construct the return ++value. */) + (Lisp_Object filename) + { + CHECK_STRING (filename); + +- /* Resolve possible symlinks in FILENAME, so that path_hash below +- always compares equal. (Bug#44701). */ +- filename = Fexpand_file_name (filename, Qnil); +- char *file_normalized = realpath (SSDATA (ENCODE_FILE (filename)), NULL); +- if (file_normalized) +- { +- filename = DECODE_FILE (make_unibyte_string (file_normalized, +- strlen (file_normalized))); +- xfree (file_normalized); +- } ++ Lisp_Object rel_name = filename; + ++ filename = Fexpand_file_name (filename, Qnil); + if (NILP (Ffile_exists_p (filename))) + xsignal1 (Qfile_missing, filename); + +@@ -4423,64 +4414,55 @@ one for the file name and another for it + filename = Fw32_long_file_name (filename); + #endif + +- Lisp_Object content_hash = comp_hash_source_file (filename); +- +- if (suffix_p (filename, ".gz")) +- filename = Fsubstring (filename, Qnil, make_fixnum (-3)); +- +- /* We create eln filenames with an hash in order to look-up these +- starting from the source filename, IOW have a relation +- +- /absolute/path/filename.el + content -> +- eln-cache/filename-path_hash-content_hash.eln. +- +- 'dlopen' can return the same handle if two shared with the same +- filename are loaded in two different times (even if the first was +- deleted!). To prevent this scenario the source file content is +- included in the hashing algorithm. +- +- As at any point in time no more then one file can exist with the +- same filename, should be possible to clean up all +- filename-path_hash-* except the most recent one (or the new one +- being recompiled). +- +- As installing .eln files compiled during the build changes their +- absolute path we need an hashing mechanism that is not sensitive +- to that. For this we replace if match PATH_DUMPLOADSEARCH or +- *PATH_REL_LOADSEARCH with '//' before computing the hash. */ +- +- if (NILP (loadsearch_re_list)) +- { +- Lisp_Object sys_re = +- concat2 (build_string ("\\`[[:ascii:]]+"), +- Fregexp_quote (build_string ("/" PATH_REL_LOADSEARCH "/"))); +- Lisp_Object dump_load_search = +- Fexpand_file_name (build_string (PATH_DUMPLOADSEARCH "/"), Qnil); +-#ifdef WINDOWSNT +- dump_load_search = Fw32_long_file_name (dump_load_search); +-#endif +- loadsearch_re_list = list2 (sys_re, Fregexp_quote (dump_load_search)); +- } ++ Lisp_Object tail = Vload_path; ++ Lisp_Object name_len = Flength (filename); + +- Lisp_Object lds_re_tail = loadsearch_re_list; +- FOR_EACH_TAIL (lds_re_tail) ++ FOR_EACH_TAIL_SAFE (tail) + { +- Lisp_Object match_idx = +- Fstring_match (XCAR (lds_re_tail), filename, Qnil, Qnil); +- if (BASE_EQ (match_idx, make_fixnum (0))) ++ Lisp_Object directory = Ffile_name_as_directory (XCAR (tail)); ++ Lisp_Object len = Flength (directory); ++ if (XFIXNUM (name_len) < XFIXNUM (len)) ++ continue; ++ else if (EQ (Qt, Fcompare_strings (filename, make_fixnum (0), len, ++ directory, make_fixnum (0), len, ++ Qnil))) + { +- filename = +- Freplace_match (build_string ("//"), Qt, Qt, filename, Qnil); ++ filename = Fsubstring (filename, len, Qnil); + break; + } + } +- Lisp_Object separator = build_string ("-"); +- Lisp_Object path_hash = comp_hash_string (filename); +- filename = concat2 (Ffile_name_nondirectory (Fsubstring (filename, Qnil, +- make_fixnum (-3))), +- separator); +- Lisp_Object hash = concat3 (path_hash, separator, content_hash); +- return concat3 (filename, hash, build_string (NATIVE_ELISP_SUFFIX)); ++ ++ if (file_name_absolute_p (filename)) /* no match in load-path */ ++ filename = rel_name; ++ ++ Lisp_Object bogus_dirs = ++ Fgetenv_internal (build_string ("NATIVE_COMP_BOGUS_DIRS"), Qnil); ++ ++ if (!NILP (bogus_dirs)) ++ { ++ tail = CALL2I (split-string, bogus_dirs, build_string (":")); ++ ++ FOR_EACH_TAIL_SAFE (tail) ++ { ++ Lisp_Object directory = Ffile_name_as_directory (XCAR (tail)); ++ Lisp_Object len = Flength (directory); ++ if (XFIXNUM (name_len) < XFIXNUM (len)) ++ continue; ++ else if (EQ (Qt, Fcompare_strings (filename, make_fixnum (0), len, ++ directory, make_fixnum (0), len, ++ Qnil))) ++ { ++ filename = Fsubstring (filename, len, Qnil); ++ break; ++ } ++ } ++ } ++ ++ if (suffix_p (filename, ".gz")) ++ filename = Fsubstring (filename, Qnil, make_fixnum (-3)); ++ ++ return concat2(Fsubstring (filename, Qnil, make_fixnum (-3)), ++ build_string (NATIVE_ELISP_SUFFIX)); + } + + DEFUN ("comp-el-to-eln-filename", Fcomp_el_to_eln_filename, +@@ -4494,13 +4476,7 @@ If BASE-DIR is non-nil, use it as the di + non-absolute BASE-DIR is interpreted as relative to `invocation-directory'. + If BASE-DIR is omitted or nil, look for the first writable directory + in `native-comp-eln-load-path', and use as BASE-DIR its subdirectory +-whose name is given by `comp-native-version-dir'. +-If FILENAME specifies a preloaded file, the directory for the .eln +-file is the \"preloaded/\" subdirectory of the directory determined +-as described above. FILENAME is considered to be a preloaded file if +-the value of `comp-file-preloaded-p' is non-nil, or if FILENAME +-appears in the value of the environment variable LISP_PRELOADED; +-the latter is supposed to be used by the Emacs build procedure. */) ++whose name is given by `comp-native-version-dir'. */) + (Lisp_Object filename, Lisp_Object base_dir) + { + Lisp_Object source_filename = filename; +@@ -4548,10 +4524,11 @@ the latter is supposed to be used by the + Lisp_Object lisp_preloaded = + Fgetenv_internal (build_string ("LISP_PRELOADED"), Qnil); + base_dir = Fexpand_file_name (Vcomp_native_version_dir, base_dir); ++ bool preloaded = comp_file_preloaded_p; + if (comp_file_preloaded_p + || (!NILP (lisp_preloaded) +- && !NILP (Fmember (CALL1I (file-name-base, source_filename), +- Fmapcar (intern_c_string ("file-name-base"), ++ && !NILP (Fmember (CALL1I (file-name-sans-extension, source_filename), ++ Fmapcar (intern_c_string ("file-name-sans-extension"), + CALL1I (split-string, lisp_preloaded)))))) + base_dir = Fexpand_file_name (build_string ("preloaded"), base_dir); + +@@ -5863,10 +5840,7 @@ The last directory of this list is assum + the system *.eln files, which are the files produced when building + Emacs. */); + +- /* Temporary value in use for bootstrap. We can't do better as +- `invocation-directory' is still unset, will be fixed up during +- dump reload. */ +- Vnative_comp_eln_load_path = Fcons (build_string ("../native-lisp/"), Qnil); ++ Vnative_comp_eln_load_path = Qnil; + + DEFVAR_LISP ("native-comp-enable-subr-trampolines", + Vnative_comp_enable_subr_trampolines, +Index: emacs-29.2/lisp/startup.el +=================================================================== +--- emacs-29.2.orig/lisp/startup.el ++++ emacs-29.2/lisp/startup.el +@@ -545,9 +545,6 @@ DIRS are relative." + (defvar native-comp-jit-compilation) + (defvar native-comp-enable-subr-trampolines) + +-(defvar startup--original-eln-load-path nil +- "Original value of `native-comp-eln-load-path'.") +- + (defun startup-redirect-eln-cache (cache-directory) + "Redirect the user's eln-cache directory to CACHE-DIRECTORY. + CACHE-DIRECTORY must be a single directory, a string. +@@ -558,22 +555,10 @@ to `user-emacs-directory'. + For best results, call this function in your early-init file, + so that the rest of initialization and package loading uses + the updated value." +- ;; Remove the original eln-cache. +- (setq native-comp-eln-load-path (cdr native-comp-eln-load-path)) +- ;; Add the new eln-cache. + (push (expand-file-name (file-name-as-directory cache-directory) + user-emacs-directory) + native-comp-eln-load-path)) + +-(defun startup--update-eln-cache () +- "Update the user eln-cache directory due to user customizations." +- ;; Don't override user customizations! +- (when (equal native-comp-eln-load-path +- startup--original-eln-load-path) +- (startup-redirect-eln-cache "eln-cache") +- (setq startup--original-eln-load-path +- (copy-sequence native-comp-eln-load-path)))) +- + (defun normal-top-level () + "Emacs calls this function when it first starts up. + It sets `command-line-processed', processes the command-line, +@@ -1362,12 +1347,6 @@ please check its value") + startup-init-directory))) + (setq early-init-file user-init-file) + +- ;; Amend `native-comp-eln-load-path', since the early-init file may +- ;; have altered `user-emacs-directory' and/or changed the eln-cache +- ;; directory. +- (when (featurep 'native-compile) +- (startup--update-eln-cache)) +- + ;; If any package directory exists, initialize the package system. + (and user-init-file + package-enable-at-startup +@@ -1502,12 +1481,6 @@ please check its value") + startup-init-directory)) + t) + +- ;; Amend `native-comp-eln-load-path' again, since the early-init +- ;; file may have altered `user-emacs-directory' and/or changed the +- ;; eln-cache directory. +- (when (featurep 'native-compile) +- (startup--update-eln-cache)) +- + (when (and deactivate-mark transient-mark-mode) + (with-current-buffer (window-buffer) + (deactivate-mark))) +Index: emacs-29.2/lisp/loadup.el +=================================================================== +--- emacs-29.2.orig/lisp/loadup.el ++++ emacs-29.2/lisp/loadup.el +@@ -53,6 +53,14 @@ + (setq redisplay--inhibit-bidi t) + + (message "Dump mode: %s" dump-mode) ++;; Compensate for native-comp-eln-load-path being empty by Guix' default. ++(and (featurep 'native-compile) ++ dump-mode ++ (setq ++ native-comp-eln-load-path ++ (cons (expand-file-name "../native-lisp" invocation-directory) ++ native-comp-eln-load-path) ++ comp-file-preloaded-p t)) + + ;; Add subdirectories to the load-path for files that might get + ;; autoloaded when bootstrapping or running Emacs normally. +@@ -494,22 +502,20 @@ lost after dumping"))) + (concat eln-dest-dir "native-lisp/" comp-native-version-dir "/")) + (maphash (lambda (_ cu) + (let* ((file (native-comp-unit-file cu)) +- (preloaded (equal (substring (file-name-directory file) +- -10 -1) +- "preloaded")) +- (eln-dest-dir-eff (if preloaded +- (expand-file-name "preloaded" +- eln-dest-dir) +- eln-dest-dir))) ++ (native-lisp-needle ++ (regexp-quote (concat "native-lisp/" ++ comp-native-version-dir "/")))) + (native-comp-unit-set-file + cu + (cons + ;; Relative filename from the installed binary. +- (file-relative-name (expand-file-name +- (file-name-nondirectory +- file) +- eln-dest-dir-eff) +- bin-dest-dir) ++ (file-relative-name ++ (expand-file-name ++ (save-match-data ++ (string-match native-lisp-needle file) ++ (substring file (match-end 0))) ++ eln-dest-dir) ++ bin-dest-dir) + ;; Relative filename from the built uninstalled binary. + (file-relative-name file invocation-directory))))) + comp-loaded-comp-units-h))) +@@ -557,7 +563,9 @@ lost after dumping"))) + (equal dump-mode "pdump")) + ;; Don't enable this before bootstrap is completed, as the + ;; compiler infrastructure may not be usable yet. +- (setq native-comp-enable-subr-trampolines t)) ++ (setq native-comp-enable-subr-trampolines t ++ ;; We loaded everything we could. ++ comp-file-preloaded-p nil)) + (message "Dumping under the name %s" output) + (condition-case () + (delete-file output) +Index: emacs-29.2/src/Makefile.in +=================================================================== +--- emacs-29.2.orig/src/Makefile.in ++++ emacs-29.2/src/Makefile.in +@@ -553,6 +553,7 @@ shortlisp := $(filter-out ${shortlisp_fi + ## We don't really need to sort, but may as well use it to remove duplicates. + shortlisp := loaddefs.el loadup.el $(sort ${shortlisp}) + export LISP_PRELOADED = ${shortlisp} ++export NATIVE_COMP_BOGUS_DIRS = + lisp = $(addprefix ${lispsource}/,${shortlisp}) + + ## Construct full set of libraries to be linked. diff --git a/gnu/packages/xorg.scm b/gnu/packages/xorg.scm index a8a67b9270..c2bf7dac58 100644 --- a/gnu/packages/xorg.scm +++ b/gnu/packages/xorg.scm @@ -6316,7 +6316,6 @@ X11 servers, Windows, or macOS.") (guix build emacs-utils)) #:configure-flags (list "--with-anthy-utf8" - (string-append "--with-lispdir=" %output "/share/emacs") ;; Set proper runpath (string-append "LDFLAGS=-Wl,-rpath=" %output "/lib") "CFLAGS=-O2 -g -fcommon") @@ -6330,21 +6329,11 @@ X11 servers, Windows, or macOS.") ("uim-el-agent" (string-append out "/bin/uim-el-agent")) ("uim-el-helper-agent" (string-append out "/bin/uim-el-helper-agent")))) #t)) - ;; Fix installation path by renaming share/emacs/uim-el to - ;; share/emacs/site-lisp - (add-after 'install 'fix-install-path - (lambda* (#:key outputs #:allow-other-keys) - (let ((share-emacs (string-append (assoc-ref outputs "out") - "/share/emacs"))) - (rename-file (string-append share-emacs "/uim-el") - (string-append share-emacs "/site-lisp"))) - #t)) - ;; Generate emacs autoloads for uim.el (add-after 'fix-install-path 'make-autoloads (lambda* (#:key outputs #:allow-other-keys) (emacs-generate-autoloads ,name (string-append (assoc-ref outputs "out") - "/share/emacs/site-lisp")) + "/share/emacs/site-lisp/uim-el")) #t))))) (home-page "https://github.com/uim/uim") (synopsis "Multilingual input method framework") diff --git a/guix/build/emacs-build-system.scm b/guix/build/emacs-build-system.scm index 3808b60445..aa083c6409 100644 --- a/guix/build/emacs-build-system.scm +++ b/guix/build/emacs-build-system.scm @@ -132,29 +132,25 @@ environment variable\n" source-directory)) (parameterize ((%emacs emacs)) (emacs-compile-directory (elpa-directory out))))) -(define* (patch-el-files #:key outputs #:allow-other-keys) - "Substitute the absolute \"/bin/\" directory with the right location in the -store in '.el' files." +(define* (patch-el-files #:key inputs outputs #:allow-other-keys) + "Substitute the absolute \"/bin/\" and \"/sbin\" directories with the right +locations in the store in '.el' files." - (let* ((out (assoc-ref outputs "out")) - (elpa-name-ver (store-directory->elpa-name-version out)) - (el-dir (string-append out %install-dir "/" elpa-name-ver)) - (el-files (find-files (getcwd) "\\.el$"))) - (define (substitute-program-names) - (substitute* el-files - (("\"/bin/([^.]\\S*)\"" _ cmd-name) - (let ((cmd (which cmd-name))) - (unless cmd - (error "patch-el-files: unable to locate " cmd-name)) - (string-append "\"" cmd "\""))))) + (define substitute-program-names + (let ((el-files (find-files (getcwd) "\\.el$"))) + (lambda () + (substitute* el-files + (("\"/(s?bin/[^.]\\S*)\"" _ cmd) + (let ((cmd (search-input-file inputs cmd))) + (unless cmd + (error "patch-el-files: unable to locate " (basename cmd))) + (string-append "\"" cmd "\""))))))) - (with-directory-excursion el-dir - ;; Some old '.el' files (e.g., tex-buf.el in AUCTeX) are still - ;; ISO-8859-1-encoded. - (unless (false-if-exception (substitute-program-names)) - (with-fluids ((%default-port-encoding "ISO-8859-1")) - (substitute-program-names)))) - #t)) + (unless (false-if-exception (substitute-program-names)) + ;; Some old '.el' files (e.g., tex-buf.el in AUCTeX) are still + ;; ISO-8859-1-encoded. + (with-fluids ((%default-port-encoding "ISO-8859-1")) + (substitute-program-names)))) (define (find-root-library-file name) (let loop ((parts (string-split @@ -224,10 +220,8 @@ store in '.el' files." (emacs-batch-edit-file (string-append name ".el") %write-pkg-file-form))) - (let* ((out (assoc-ref outputs "out")) - (elpa-name-ver (store-directory->elpa-name-version out))) - (with-directory-excursion (elpa-directory out) - (and=> (find-root-library-file elpa-name-ver) write-pkg-file)))) + (let ((name (store-directory->elpa-name-version (assoc-ref outputs "out")))) + (and=> (find-root-library-file name) write-pkg-file))) (define* (check #:key tests? (test-command '("make" "check")) (parallel-tests? #t) #:allow-other-keys) @@ -306,24 +300,15 @@ parallel. PARALLEL-TESTS? is ignored when using a non-make TEST-COMMAND." info-files))) #t)) -(define* (make-autoloads #:key outputs inputs #:allow-other-keys) +(define* (make-autoloads #:key outputs #:allow-other-keys) "Generate the autoloads file." - (let* ((emacs (search-input-file inputs "/bin/emacs")) - (out (assoc-ref outputs "out")) - (elpa-name-ver (store-directory->elpa-name-version out)) - (elpa-name (package-name->name+version elpa-name-ver)) - (el-dir (elpa-directory out))) - (parameterize ((%emacs emacs)) - (emacs-generate-autoloads elpa-name el-dir)))) - -(define* (enable-autoloads-compilation #:key outputs #:allow-other-keys) - "Remove the NO-BYTE-COMPILATION local variable embedded in the generated -autoload files." - (let* ((out (assoc-ref outputs "out")) - (autoloads (find-files out "-autoloads.el$"))) - (substitute* autoloads - ((";; no-byte-compile.*") "")) - #t)) + (emacs-generate-autoloads + (package-name->name+version (store-directory->elpa-name-version + (assoc-ref outputs "out"))) + (getcwd)) + ;; Ensure that autoloads can be byte-compiled. + (substitute* (find-files "." "-autoloads\\.el$") + ((";; no-byte-compile.*") ""))) (define* (validate-compiled-autoloads #:key outputs #:allow-other-keys) "Verify whether the byte compiled autoloads load fine." @@ -358,7 +343,11 @@ for libraries following the ELPA convention." (define %standard-phases (modify-phases gnu:%standard-phases (replace 'unpack unpack) + (add-after 'unpack 'ensure-package-description + ensure-package-description) (add-after 'unpack 'expand-load-path expand-load-path) + (add-after 'unpack 'patch-el-files patch-el-files) + (add-after 'expand-load-path 'make-autoloads make-autoloads) (add-after 'expand-load-path 'add-install-to-native-load-path add-install-to-native-load-path) (delete 'bootstrap) @@ -366,14 +355,8 @@ for libraries following the ELPA convention." (delete 'build) (replace 'check check) (replace 'install install) - (add-after 'install 'make-autoloads make-autoloads) - (add-after 'make-autoloads 'enable-autoloads-compilation - enable-autoloads-compilation) - (add-after 'enable-autoloads-compilation 'patch-el-files patch-el-files) - (add-after 'patch-el-files 'ensure-package-description - ensure-package-description) ;; The .el files are byte compiled directly in the store. - (add-after 'ensure-package-description 'build build) + (add-after 'install 'build build) (add-after 'build 'validate-compiled-autoloads validate-compiled-autoloads) (add-after 'validate-compiled-autoloads 'move-doc move-doc))) diff --git a/guix/build/emacs-utils.scm b/guix/build/emacs-utils.scm index 8e12b5b6d4..aeb364133a 100644 --- a/guix/build/emacs-utils.scm +++ b/guix/build/emacs-utils.scm @@ -136,7 +136,14 @@ If native code is not supported, compile to bytecode instead." (emacs-batch-eval `(let ((byte-compile-debug t) ; for proper exit status (byte+native-compile (native-comp-available-p)) - (files (directory-files-recursively ,dir "\\.el$"))) + (files (directory-files-recursively ,dir "\\.el$")) + (write-bytecode + (and (native-comp-available-p) + (progn + (require 'comp) + (if (fboundp 'comp-write-bytecode-file) + 'comp-write-bytecode-file + 'comp--write-bytecode-file))))) (mapc (lambda (file) (let (byte-to-native-output-buffer-file @@ -146,11 +153,13 @@ If native code is not supported, compile to bytecode instead." (cadr native-comp-eln-load-path)))) (if byte+native-compile (native-compile file - (comp-el-to-eln-filename file eln-dir)) + (comp-el-to-eln-filename + (file-relative-name file ,dir) + eln-dir)) (byte-compile-file file)) ;; After native compilation, write the bytecode file. (unless (null byte-to-native-output-buffer-file) - (comp-write-bytecode-file nil)))) + (funcall write-bytecode nil)))) files)) #:dynamic? #t))