Subject: bug#75812: 29.2.50; Support native-compiling package-install from batch Emacs

From: Spencer Baugh <[email-masked]>
Date: Thu, 24 Apr 2025 17:25:47 -0400

Eli Zaretskii <[email-masked]> writes:

>> From: Spencer Baugh <[email-masked]>
>> Cc: Andrea Corallo <[email-masked]>,  Eli Zaretskii <[email-masked]>,
>>    [email-masked],  [email-masked],
>>    [email-masked]
>> Date: Wed, 23 Apr 2025 12:26:44 -0400
>> 
>> 
>> Conveniently there's already a hook, native-comp-async-all-done-hook,
>> which gets called when the async native compilation is done.  I just
>> need to synchronously wait for that hook to be called.
>> 
>> So what about something like this?
>> 
>> (defun native-comp-async-wait-for-all-done ()
>>   (unless (zerop (comp--async-runnings))
>>     (let* ((native-comp-finished-pipe (make-pipe-process :name "native-comp-finished"))
>>            (native-comp-async-all-done-hook (list (lambda () (delete-process native-comp-finished-pipe)))))
>>       (accept-process-output native-comp-finished-pipe))))
>> 
>> The use of a pipe process is weird, but I don't know of a better way to
>> wait for a hook to be called.
>
> That will not work on Windows, so let's not.

Fair.

> I don't understand why you need all that complexity.  Why not loop
> calling comp--async-runnings as long as it returns non-nil, each time
> sleeping for, say, 0.5 sec?

Sleeping for 0.5 sec means that building a package will take an extra
.25 seconds on average, which adds up over hundreds of packages.
Sleeping for 0.0001 sec wastes CPU, which also adds up over hundreds of
packages.

> Or why not install a native-comp-async-all-done-hook that will notice
> when compilations are done and allow the batch job to exit?  All you
> need is a means to wait until all the async compilations are finished,
> no?

How do you propose to do that?  I guess I could call kill-emacs from the
hook, but I have more code I want to run after the native compilation is
finished, and I can't move it all into the hook.

>> There's another related issue for the packaging use case I mentioned in
>> my original email: The .eln files are placed in ~/.emacs.d/eln-cache/ by
>> default when doing this native compilation.  That complicates building
>> and installing these packages independently.  Is there a way to put the
>> .eln files for a package in that individual package directory instead?
>
> You need to tweak native-comp-eln-load-path, e.g. prepend to the
> default-value list the directory where you want the *.eln files to be
> written.  But you are well advised to leave the other directories in
> the list alone.

Makes sense.

Does that mean that, if I want the .eln files to be loaded from the
individual package directory, I have to put every single package
directory on native-comp-eln-load-path at runtime?  That seems annoying,
and probably slow.

Is there a way to get an .eln file to be loaded from the directory the
.elc file was found in?  Maybe that just happens by default before
searching native-comp-eln-load-path?