Subject: 30.0.50; Unable to install external packages with Nix after recent native-compilation changes

From: Brian Leung <[email-masked]>
Date: Thu, 25 May 2023 11:12:58 +0000

Starting with the recent batch of native-comp commits ending with 
and including Emacs commit 
b2b2be98da5825e6bc130999ffe38f5ed615586a, using the Nix package 
manager I cannot install an Emacs containing natively-compiled 
external packages. (I have no problems on Emacs commit 
f4de81af8fc54ef278cdb76fbc5885ed7d05b2d7, which is the commit 
immediately preceding the first of the recent native-comp commits)

Building core Emacs (with native compilation) is successful, but I 
encounter problems upon running 
(https://github.com/nixos/nixpkgs/blob/8fbdc4e6114795323ad2b74d13e1c842c5618b78/pkgs/build-support/emacs/melpa.nix#L99-L102):

>    emacs --batch -Q \
>        -l "$elpa2nix" \
>        -f elpa2nix-install-package \
>        "$archive" "$out/share/emacs/site-lisp/elpa"

This fails when trying to run package-tar-file-info 
(https://github.com/nixos/nixpkgs/blob/8fbdc4e6114795323ad2b74d13e1c842c5618b78/pkgs/build-support/emacs/elpa2nix.el#L14-L15). The 
full backtrace is here:

>    Error: error ("Can't find define-package in 
>    vterm-20230417.424/vterm-pkg.el")
>    mapbacktrace(#f(compiled-function (evald func args flags) 
>    #<bytecode -0xe76c55f6510e41>))
>    debug-early-backtrace()
>    debug-early(error (error "Can't find define-package in 
>    vterm-20230417.424/vterm-pkg.el"))
>    error("Can't find define-package in %s" 
>    "vterm-20230417.424/vterm-pkg.el")
>    package-tar-file-info()
>    (if (derived-mode-p 'tar-mode) (package-tar-file-info) 
>    (package-buffer-info))
>    (let ((pkg-desc (if (derived-mode-p 'tar-mode) 
>    (package-tar-file-info) (package-buffer-info)))) 
>    (package-unpack pkg-desc) pkg-desc)
>    elpa2nix-install-from-buffer()
>    (progn (if is-tar (insert-file-contents-literally file) 
>    (insert-file-contents file)) (if is-tar (progn (tar-mode))) 
>    (elpa2nix-install-from-buffer))
>    (unwind-protect (progn (if is-tar 
>    (insert-file-contents-literally file) (insert-file-contents 
>    file)) (if is-tar (progn (tar-mode))) 
>    (elpa2nix-install-from-buffer)) (and (buffer-name 
>    temp-buffer) (kill-buffer temp-buffer)))
>    (save-current-buffer (set-buffer temp-buffer) (unwind-protect 
>    (progn (if is-tar (insert-file-contents-literally file) 
>    (insert-file-contents file)) (if is-tar (progn (tar-mode))) 
>    (elpa2nix-install-from-buffer)) (and (buffer-name 
>    temp-buffer) (kill-buffer temp-buffer))))
>    (let ((temp-buffer (generate-new-buffer " *temp*" t))) 
>    (save-current-buffer (set-buffer temp-buffer) (unwind-protect 
>    (progn (if is-tar (insert-file-contents-literally file) 
>    (insert-file-contents file)) (if is-tar (progn (tar-mode))) 
>    (elpa2nix-install-from-buffer)) (and (buffer-name 
>    temp-buffer) (kill-buffer temp-buffer)))))
>    (let ((is-tar (string-match "\\.tar\\'" file))) (let 
>    ((temp-buffer (generate-new-buffer " *temp*" t))) 
>    (save-current-buffer (set-buffer temp-buffer) (unwind-protect 
>    (progn (if is-tar (insert-file-contents-literally file) 
>    (insert-file-contents file)) (if is-tar (progn (tar-mode))) 
>    (elpa2nix-install-from-buffer)) (and (buffer-name 
>    temp-buffer) (kill-buffer temp-buffer))))))
>    elpa2nix-install-file("/build/packages/vterm-20230417.424.tar")
>    (progn (setq package-user-dir elpa) (elpa2nix-install-file 
>    archive))
>    (let ((archive x0) (elpa x2)) (progn (setq package-user-dir 
>    elpa) (elpa2nix-install-file archive)))
>    (if (null x3) (let ((archive x0) (elpa x2)) (progn (setq 
>    package-user-dir elpa) (elpa2nix-install-file archive))))
>    (let* ((x2 (car-safe x1)) (x3 (cdr-safe x1))) (if (null x3) 
>    (let ((archive x0) (elpa x2)) (progn (setq package-user-dir 
>    elpa) (elpa2nix-install-file archive)))))
>    (if (consp x1) (let* ((x2 (car-safe x1)) (x3 (cdr-safe x1))) 
>    (if (null x3) (let ((archive x0) (elpa x2)) (progn (setq 
>    package-user-dir elpa) (elpa2nix-install-file archive))))))
>    (let* ((x0 (car-safe command-line-args-left)) (x1 (cdr-safe 
>    command-line-args-left))) (if (consp x1) (let* ((x2 (car-safe 
>    x1)) (x3 (cdr-safe x1))) (if (null x3) (let ((archive x0) 
>    (elpa x2)) (progn (setq package-user-dir elpa) 
>    (elpa2nix-install-file archive)))))))
>    (if (consp command-line-args-left) (let* ((x0 (car-safe 
>    command-line-args-left)) (x1 (cdr-safe 
>    command-line-args-left))) (if (consp x1) (let* ((x2 (car-safe 
>    x1)) (x3 (cdr-safe x1))) (if (null x3) (let ((archive x0) 
>    (elpa x2)) (progn (setq package-user-dir elpa) 
>    (elpa2nix-install-file archive))))))))
>    elpa2nix-install-package()
>    command-line-1(("-l" 
>    "/nix/store/4jj63z4v1xp13rh2md053dccq920hd45-elpa2nix.el" 
>    "-f" "elpa2nix-install-package" 
>    "/build/packages/vterm-20230417.424.tar" 
>    "/nix/store/rf3rsbn6sa1l5v8pbsk02g0nrm5a7pnr-emacs-vterm-20230417.424/share/emacs/site-lisp/elpa"))
>    command-line()
>    normal-top-level()

I do not encounter any problems if I do not native-compile, or if 
I use an earlier commit as I mentioned.

Unlike the possibly-related and unresolved bug#63288, the error I 
am now getting appears to be consistently reproducible when I 
revert ea9831bb3cb4878273f6f848051c9b8c3c76d5f1, which in a Nix 
sandbox would non-deterministically cause external packages to 
fail during native compilation. I have also noticed the same error 
occurring when I leave ea9831bb3cb4878273f6f848051c9b8c3c76d5f1 
unreverted, though I haven't tested this latter scenario often 
enough to be sure that ea9831bb3cb4878273f6f848051c9b8c3c76d5f1 
has no impact since I was worried that the non-determinism would 
complicate things.

CCing Andrea Corallo.