3

I would like the eln-cache for natively compiled files (I'm using emacs 29, built from the master branch) to be in a custom location. I have this in the opening of my early-init.el file:

;; Dir for eln-cache
(when (boundp 'native-comp-eln-load-path)
  (setcar native-comp-eln-load-path
          (expand-file-name (convert-standard-filename ".local/temp/cache/eln-cache/")
                            user-emacs-directory)))

;; Silence nativecomp warnings popping up
(setq native-comp-async-report-warnings-errors nil)

;; Settings
(setq native-comp-speed 2
      native-comp-deferred-compilation t
      package-native-compile t)

Unfortunately this doesn't seem to work. I will get a few files compiled in the proper place (i.e. in the cache dir) right at the start-up of emacs but a new eln-cache dir is always also created at the root of my .emacs.d and the eln files are all then subsequently created there as well.

I don't understand what the problem is here. Any ideas are welcome.

EDIT: Here's the bug report I filed: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=53891

mclear
  • 1,525
  • 9
  • 17
  • 2
    I’m voting to close this question because the associated bug report suggests that it's a problem only in the current master branch, so it's probably not going to be useful to have a Q&A here. – phils Feb 09 '22 at 09:27
  • Something got edited? Did a comment get deleted? I don't see an associated bug report here. – NickD Feb 09 '22 at 21:13
  • I sent a bug report to check whether something had recently changed in the master branch. This was the crux of Eli's reply: "This was never supported. That it used to work for you was just luck. ... we should support it correctly: by making the "eln-cache" directory name customizable instead of hard-coded. I will work on adding such a feature. Please stay tuned." – mclear Feb 09 '22 at 22:39
  • Could you add a link to the bug report to your question? – NickD Feb 12 '22 at 13:33

2 Answers2

2

As it turns out there is not currently an emacs developer-sanctioned way to reliably customize the location of the eln-cache, though this may be coming in emacs 29, at some point in the future. Something like

(when (boundp 'native-comp-eln-load-path)
  (setcar native-comp-eln-load-path
          (expand-file-name (convert-standard-filename ".local/temp/cache/eln-cache/")
                            user-emacs-directory)))

should work on emacs 28 or early branches of 29, but don't expect it to work reliably until a customizable solution has been added.

EDIT: this has already(!) been resolved by the developers. You can now put the following in your early-init file and all will work as expected:

;; Set eln-cache dir
(when (boundp 'native-comp-eln-load-path)
  (startup-redirect-eln-cache (expand-file-name "/path/to/cache/eln-cache/" user-emacs-directory)))

Note the function (startup-redirect-eln-cache).

mclear
  • 1,525
  • 9
  • 17
0

See normal-top-level in startup.el for where that happens. That same function subsequently calls command-line to process your init files (both early-init-el and init.el), so whatever you do there should be sticking unless there's something else again messing with the value. I tried your code in 28.0.90 and couldn't replicate the problem, though, so whatever that "something else" is seems non-standard to me (at least in this version).

You could use emacs-startup-hook to act after other start-up procedures, or to check what the value is at that point in the proceedings. Failing that, I'd suggest using a variable watcher to try to track down when it's getting modified. See C-hig (elisp)Watching Variables for that.


It does indeed seem that native-comp-eln-load-path is used when deciding where to write .eln files. See C-hv comp-el-to-eln-filename for details.

You could also set native-compile-target-directory, although it's not clear to me that this is safe, so it's probably better to manipulate the path list.

Of course you could always just symlink your preferred location to ~/.emacs.d/eln-cache (which is all I did when I'd had a similar requirement).

phils
  • 48,657
  • 3
  • 76
  • 115
  • I tried using these hooks and it is still adding the eln-cache file. Somehow `"/.emacs.d/eln-cache/"` always gets added as the first entry, which means that all the eln files end up going there. – mclear Feb 08 '22 at 16:01
  • And if I try setting it directly as with `(setq native-comp-eln-load-path \`(,(expand-file-name (convert-standard-filename ".local/temp/cache/eln-cache/")) "/Applications/Emacs.app/Contents/Frameworks/native-lisp/"))` the value after startup is `("/Users/roambot/.emacs.d/eln-cache/" "/Applications/Emacs.app/Contents/Frameworks/native-lisp/")`. So it is clearly getting reset in the process in a way that ignores both `emacs-startup-hook` and `after-init-hook` (both of which I've tried). – mclear Feb 08 '22 at 16:11
  • You can't stop it from adding to the path at start-up; as I've indicated, that behaviour is hard-coded. But you can act shortly after that and make any manipulations that you wish to. That said, I just tried your code in 28.0.90 and can't replicate your problem -- in `emacs-startup-hook` I see your modified path. – phils Feb 08 '22 at 21:17
  • Actually I'd misread the sequencing. It doesn't explain your problem, but it meant my answer was misleading. I've updated it. – phils Feb 08 '22 at 21:34