about summary refs log tree commit diff
path: root/pkgs/build-support/emacs
diff options
context:
space:
mode:
authorRobert Helgesson <robert@rycee.net>2021-10-07 00:31:03 +0200
committerRobert Helgesson <robert@rycee.net>2021-11-14 22:31:48 +0100
commit3247e757416496ef6a19fb53ffdc4c92c969f39a (patch)
tree9480330dae2bedfaa73edfdbdb8318c1280ce5cf /pkgs/build-support/emacs
parent64d7a3266b6327521cfb563d014c4e26876f4dfa (diff)
emacs: resolve wrapper load-path at build time
Since the included package set is determined at build time we can also
generate the `subdirs.el` file at build time. This improves startup
time somewhat since we don't have to traverse the directory to add to
`load-path`.

For example,

``` sh-session
$ bench './emacs-old -Q --batch --kill' './emacs-new -Q --batch --kill'
benchmarking bench/./emacs-old -Q --batch --kill
time                 72.77 ms   (71.66 ms .. 73.65 ms)
                     1.000 R²   (0.999 R² .. 1.000 R²)
mean                 72.49 ms   (72.06 ms .. 72.92 ms)
std dev              746.5 μs   (582.4 μs .. 1.008 ms)

benchmarking bench/./emacs-new -Q --batch --kill
time                 40.56 ms   (40.24 ms .. 40.86 ms)
                     1.000 R²   (0.999 R² .. 1.000 R²)
mean                 40.30 ms   (40.12 ms .. 40.51 ms)
std dev              401.9 μs   (311.1 μs .. 555.8 μs)
```

The change does not actually affect the content of `load-path`:

``` sh-session
$ diff -s <(./emacs-old --batch --eval '(prin1 load-path)' | sed -E 's!/nix/store/[[:alnum:]]{32}-!!g') \
          <(./emacs-new --batch --eval '(prin1 load-path)' | sed -E 's!/nix/store/[[:alnum:]]{32}-!!g')
Files /dev/fd/63 and /dev/fd/62 are identical
```

So in principle the only observable effect should be the improved
startup time.
Diffstat (limited to 'pkgs/build-support/emacs')
-rw-r--r--pkgs/build-support/emacs/mk-wrapper-subdirs.el6
-rw-r--r--pkgs/build-support/emacs/wrapper.nix9
2 files changed, 13 insertions, 2 deletions
diff --git a/pkgs/build-support/emacs/mk-wrapper-subdirs.el b/pkgs/build-support/emacs/mk-wrapper-subdirs.el
new file mode 100644
index 0000000000000..7d30400a5c65f
--- /dev/null
+++ b/pkgs/build-support/emacs/mk-wrapper-subdirs.el
@@ -0,0 +1,6 @@
+(defmacro mk-subdirs-expr (path)
+  `(setq load-path
+         (delete-dups (append '(,path)
+                              ',(let ((default-directory path))
+                                  (normal-top-level-add-subdirs-to-load-path))
+                              load-path))))
diff --git a/pkgs/build-support/emacs/wrapper.nix b/pkgs/build-support/emacs/wrapper.nix
index ccbd58485ea8b..2aa61d6d2f62f 100644
--- a/pkgs/build-support/emacs/wrapper.nix
+++ b/pkgs/build-support/emacs/wrapper.nix
@@ -165,8 +165,13 @@ runCommand
           (add-to-list 'native-comp-eln-load-path "$out/share/emacs/native-lisp/")
         ''}
         EOF
-        # Link subdirs.el from the emacs distribution
-        ln -s $emacs/share/emacs/site-lisp/subdirs.el -T $subdirs
+
+        # Generate a subdirs.el that statically adds all subdirectories to load-path.
+        $emacs/bin/emacs \
+          --batch \
+          --load ${./mk-wrapper-subdirs.el} \
+          --eval "(prin1 (macroexpand-1 '(mk-subdirs-expr \"$out/share/emacs/site-lisp\")))" \
+          > "$subdirs"
 
         # Byte-compiling improves start-up time only slightly, but costs nothing.
         $emacs/bin/emacs --batch -f batch-byte-compile "$siteStart" "$subdirs"