emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Building a release tarball generates trampoline files in eln-cache


From: Andrea Corallo
Subject: Re: Building a release tarball generates trampoline files in eln-cache
Date: Thu, 11 Nov 2021 21:01:37 +0000
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Andrea Corallo <akrl@sdf.org>
>> Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org
>> Date: Thu, 11 Nov 2021 15:08:16 +0000
>> 
>> Eli Zaretskii <eliz@gnu.org> writes:
>> 
>> > You mean, bind no-native-compile to a non-nil value until after some
>> > point in startup.el?
>> 
>> I was thinking to something a little different like recording what we
>> wanted to compile when it was not possible cause too early in the
>> startup.
>> 
>> When startup is finished if this list of pending files is not empty we
>> should load comp.el (and its dependencies) and then consume the list of
>> pending .el files to be compiled (possibly including comp.el as well).
>> 
>> > That could work (I actually tried that, but
>> > under the assumption that xterm.el was the problem, so it didn't
>> > help).  But why do you think this problem happens only early during
>> > startup?  Suppose we cross that bridge, and then Emacs needs to load
>> > some Lisp file that wasn't natively-compiled -- won't we have the same
>> > problem and for the same reason?  The first gv-get in the backtrace is
>> > called as part of compiling, so it sounds like every compilation is in
>> > the danger of triggering this problem, because compiling needs
>> > gv-setter again.  Or what am I missing?
>> 
>> The first `gv-get' is part of a byte compilation.  With the proposed
>> mechanism it should go through postponing the comp.el load to say when
>> we return to `normal-top-level'.
>> 
>> That's not a trivial problem, I might be missing something I don't see
>> ATM.
>
> Would the code to implement this be complicated?  If not, please show
> the code you had in mind, so I could make sure we are on the same
> page.

I'm attaching the following patch.  It is very much untested but should
clarify what I had in mind.

diff --git a/lisp/startup.el b/lisp/startup.el
index 505d7b83f4..fe51c1de64 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -519,6 +519,18 @@ startup--xdg-or-homedot
       xdg-dir)
      (t emacs-d-dir))))
 
+(defvar comp--delayed-sources)
+(defvar comp--loadable)
+(declare-function native--compile-async "comp.el"
+                  (files &optional recursively load selector))
+(defun honor-delayed-native-compilations ()
+  (when (native-comp-available-p)
+    (setq comp--loadable t)
+    (when comp--delayed-sources
+      (require 'comp)
+      (native--compile-async comp--delayed-sources nil 'late)
+      (setq comp--delayed-sources nil))))
+
 (defvar native-comp-eln-load-path)
 (defun normal-top-level ()
   "Emacs calls this function when it first starts up.
@@ -785,7 +797,8 @@ normal-top-level
           (if (string-match "\\`DISPLAY=" varval)
               (setq display varval))))
       (when display
-        (delete display process-environment)))))
+        (delete display process-environment))))
+  (honor-delayed-native-compilations))
 
 ;; Precompute the keyboard equivalents in the menu bar items.
 ;; Command-line options supported by tty's:
diff --git a/src/comp.c b/src/comp.c
index bc1adcf4e2..900e2ee82a 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -4786,10 +4786,6 @@ register_native_comp_unit (Lisp_Object comp_u)
 /* Deferred compilation mechanism. */
 /***********************************/
 
-/* List of sources we'll compile and load after having conventionally
-   loaded the compiler and its dependencies.  */
-static Lisp_Object delayed_sources;
-
 /* Queue an asynchronous compilation for the source file defining
    FUNCTION_NAME and perform a late load.
 
@@ -4846,30 +4842,16 @@ maybe_defer_native_compilation (Lisp_Object 
function_name,
 
   /* This is so deferred compilation is able to compile comp
      dependencies breaking circularity.  */
-  if (!NILP (Ffeaturep (Qcomp, Qnil)))
+  if (comp__loadable)
     {
-      /* Comp already loaded.  */
-      if (!NILP (delayed_sources))
-       {
-         CALLN (Ffuncall, intern_c_string ("native--compile-async"),
-                delayed_sources, Qnil, Qlate);
-         delayed_sources = Qnil;
-       }
+      /* Startup is done, comp is usable.  */
+      Frequire (Qcomp, Qnil, Qnil);
       Fputhash (function_name, definition, Vcomp_deferred_pending_h);
       CALLN (Ffuncall, intern_c_string ("native--compile-async"),
             src, Qnil, Qlate);
     }
   else
-    {
-      delayed_sources = Fcons (src, delayed_sources);
-      /* Require comp only once.  */
-      static bool comp_required = false;
-      if (!comp_required)
-       {
-         comp_required = true;
-         Frequire (Qcomp, Qnil, Qnil);
-       }
-    }
+    Vcomp__delayed_sources = Fcons (src, Vcomp__delayed_sources);
 }
 
 
@@ -5327,6 +5309,13 @@ DEFUN ("native-comp-available-p", 
Fnative_comp_available_p,
 syms_of_comp (void)
 {
 #ifdef HAVE_NATIVE_COMP
+  DEFVAR_LISP ("comp--delayed-sources", Vcomp__delayed_sources,
+              doc: /* List of sources to be native compiled when
+                      startup is finished.  For internal use.  */);
+  DEFVAR_BOOL ("comp--loadable",
+              comp__loadable,
+              doc: /* Non-nil when comp.el can be loaded.  For
+                      internal use. */);
   /* Compiler control customizes.  */
   DEFVAR_BOOL ("native-comp-deferred-compilation",
               native_comp_deferred_compilation,
@@ -5467,8 +5456,6 @@ syms_of_comp (void)
   staticpro (&comp.func_blocks_h);
   staticpro (&comp.emitter_dispatcher);
   comp.emitter_dispatcher = Qnil;
-  staticpro (&delayed_sources);
-  delayed_sources = Qnil;
   staticpro (&loadsearch_re_list);
   loadsearch_re_list = Qnil;
 
> And while I have your attention, another question: suppose that Emacs
> with all the preloaded files compiled to *.eln is installed on a
> system that has libgccjit (which AFAIU is necessary to run the
> native-compiled code), but doesn't have Binutils -- what will happen
> when Emacs loads some .el file and tries to compile it?  Will the
> response to the compilation failure be graceful?  (This situation is
> likely to happen when users install a binary distro, but don't have
> Binutils available.)

I believe binutils is a dependecy of libgccjit, so I guess having
libgccjit without binutils should be classified as missconfiguration no?

Regards

  Andrea

reply via email to

[Prev in Thread] Current Thread [Next in Thread]