~ruther/guix-local

72ca1a336ab296187a4d025c399fade63004c780 — Liliana Marie Prikler 2 years ago a915a57 + ce999ae
Merge branch 'emacs-team'
M Makefile.am => Makefile.am +1 -0
@@ 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			\

M gnu/local.mk => gnu/local.mk +2 -0
@@ 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  \

A gnu/packages/aux-files/emacs/comp-integrity.el => gnu/packages/aux-files/emacs/comp-integrity.el +132 -0
@@ 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)

M gnu/packages/dictionaries.scm => gnu/packages/dictionaries.scm +4 -4
@@ 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

M gnu/packages/emacs-xyz.scm => gnu/packages/emacs-xyz.scm +24 -23
@@ 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 <https://gitlab.com/emacs-geiser/chez/-/issues/7>.


@@ 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))

M gnu/packages/emacs.scm => gnu/packages/emacs.scm +27 -7
@@ 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"

M gnu/packages/guile-xyz.scm => gnu/packages/guile-xyz.scm +3 -3
@@ 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))

M gnu/packages/language.scm => gnu/packages/language.scm +3 -3
@@ 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")

M gnu/packages/mail.scm => gnu/packages/mail.scm +17 -13
@@ 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")))))
         (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
         (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 'emacs-build
         (add-after 'install 'install-emacs-mode
           (assoc-ref emacs:%standard-phases 'install))
         (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)))))

A gnu/packages/patches/emacs-disable-jit-compilation.patch => gnu/packages/patches/emacs-disable-jit-compilation.patch +19 -0
@@ 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");

A gnu/packages/patches/emacs-native-comp-fix-filenames.patch => gnu/packages/patches/emacs-native-comp-fix-filenames.patch +338 -0
@@ 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.

M gnu/packages/xorg.scm => gnu/packages/xorg.scm +1 -12
@@ 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")

M guix/build/emacs-build-system.scm => guix/build/emacs-build-system.scm +34 -51
@@ 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."

  (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 "\"")))))

    (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))
(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."

  (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 "\"")))))))

  (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)))


M guix/build/emacs-utils.scm => guix/build/emacs-utils.scm +12 -3
@@ 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))