Subject: Re: bug#64226: 30.0.50; emacs-lisp-native-compile-and-load permission error

From: No Wayman <[email-masked]>
Date: Sat, 01 Jul 2023 15:14:16 -0400

Eli Zaretskii <[email-masked]> writes:

> perhaps you could describe how to
> reproduce starting from "emacs -Q" (and loading any packages or
> features you need for the minimal reproduction recipe).  The way 
> you
> were showing the problem until now obviously depends on your 
> local
> setup, which is impossible to reproduce without knowing the 
> details.

The instructions I gave here:

https://lists.gnu.org/archive/html/bug-gnu-emacs/2023-06/msg01224.html

reproduce the error on my end from emacs -Q with a minimal file.
To be crystal clear:

1. Save the following file to $HOME/test.el (or any path where the 
user has write permissions):

--8<---------------cut here---------------start------------->8---
;; -*- lexical-binding: t; -*-
(defun +test () (message "PASS"))
--8<---------------cut here---------------end--------------->8---

2. emacs -Q $HOME/test.el
3. M-x emacs-lisp-native-compile-compile-and-load
4. Error is printed to message buffer.

I'm not sure how I can meaningfully pare it down from there.

> The main aspect of this which is completely unclear is: how come 
> Emacs
> tries to write in the /usr/lib tree when compiling Lisp files 
> from
> your home directory.  This is not supposed to happen: Emacs 
> should
> write to the eln-cache subdirectory of your ~/.emacs.d/ 
> directory.

That makes sense to me and I agree.
It looks like the critical path is in the file 
`comp-spill-lap-function' method.
The comp-ctxt-output slot is set to (car (last 
native-comp-eln-load-path)).

I don't know enough about the native-comp machinery to say whether 
or not this is the appropriate solution, but let-binding 
`native-compile-target-directory' to the car of 
native-comp-eln-load-path in emacs-lisp-native-compile-and-load 
compiles in the correct directory and avoids the error:

(defun emacs-lisp-native-compile-and-load ()
  "Native-compile synchronously the current file (if it has 
  changed).
Load the compiled code when finished.

Use `emacs-lisp-byte-compile-and-load' in combination with
`native-comp-jit-compilation' set to t to achieve asynchronous
native compilation."
  (interactive nil emacs-lisp-mode)
  (emacs-lisp--before-compile-buffer)
  (let ((byte+native-compile t)
        (native-compile-target-directory (car 
        native-comp-eln-load-path))
        (byte-to-native-output-buffer-file nil))
    (when-let ((eln (native-compile buffer-file-name)))
      (load (file-name-sans-extension (comp-write-bytecode-file 
      eln))))))

I'll leave the work of a proper patch to someone who is more 
familiar with the system.