-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
emacsWithPackages runs emacs with invocation-directory of nested package #145302
Comments
cc @adisbladis
|
I think I've tracked down the source of the problem, which affects versions of Emacs built with Home Manager. The trivial substitute ${./wrapper.sh} $out/Applications/Emacs.app/Contents/MacOS/Emacs \
--subst-var-by bash ${emacs.stdenv.shell} \
--subst-var-by wrapperSiteLisp "$deps/share/emacs/site-lisp" \
--subst-var-by wrapperSiteLispNative "$deps/share/emacs/native-lisp" \
--subst-var-by prog "$emacs/Applications/Emacs.app/Contents/MacOS/Emacs"
chmod +x $out/Applications/Emacs.app/Contents/MacOS/Emacs
wrapProgramBinary $out/Applications/Emacs.app/Contents/MacOS/Emacs If you have Home Manager setup, you can reproduce the issue with the following configuration: {
programs.emacs = {
enable = true;
package = pkgs.emacs-unstable-pgtk;
extraPackages = epkgs: [epkgs.vterm];
overrides = final: prev: {
# `emacs-28` patches are compatible with `emacs-29`.
#
# Where a compatible path exists, there is a symlink upstream to keep
# things clean, but GitHub doesn't follow symlinks to generate the
# responses we need (instead GitHub returns the target of the symlink).
patches =
(prev.patches or [])
++ [
# Fix OS window role (needed for window managers like yabai)
(pkgs.fetchpatch {
url = "https://raw.githubusercontent.com/d12frosted/homebrew-emacs-plus/master/patches/emacs-28/fix-window-role.patch";
sha256 = "0c41rgpi19vr9ai740g09lka3nkjk48ppqyqdnncjrkfgvm2710z";
})
# Use poll instead of select to get file descriptors
(pkgs.fetchpatch {
url = "https://raw.githubusercontent.com/d12frosted/homebrew-emacs-plus/master/patches/emacs-29/poll.patch";
sha256 = "0j26n6yma4n5wh4klikza6bjnzrmz6zihgcsdx36pn3vbfnaqbh5";
})
# Enable rounded window with no decoration
(pkgs.fetchpatch {
url = "https://raw.githubusercontent.com/d12frosted/homebrew-emacs-plus/master/patches/emacs-29/round-undecorated-frame.patch";
sha256 = "0x187xvjakm2730d1wcqbz2sny07238mabh5d97fah4qal7zhlbl";
})
# Make Emacs aware of OS-level light/dark mode
(pkgs.fetchpatch {
url = "https://raw.githubusercontent.com/d12frosted/homebrew-emacs-plus/master/patches/emacs-28/system-appearance.patch";
sha256 = "14ndp2fqqc95s70fwhpxq58y8qqj4gzvvffp77snm2xk76c1bvnn";
})
];
};
};
} |
Mentioning Emacs maintainers for input before I open a pull request to fix this: @AndersonTorres @adisbladis @Atemu @jwiegley @lovek323 @matthewbauer I'm working on a reproducible example of this issue to ease testing, and I think I know what's causing the problem — while the Would a pull request that applies the with-packages rename in both places solve this problem? If so, I'll work on something along those lines this weekend. Update: I've tested my hypothesis locally, and it doesn't fix the problem. Executing the original Emacs derivation (sans with-packages suffix) is the desired behaviour. If, instead, you execute the with-packages version, Emacs never finishes launching. Back to the drawing board! |
The other thing appears to be affected by this - native compilation, which also uses The change introduced in #106486 (commit 23d4bfb) says that load-path sanitization is only for convenience when hacking on emacs itself or it's nixpkgs packaging. Now that it's affecting 2 core features of emacs itself - The last test case of the following shell script shows that without sanitization (as it's inhibited by #!/usr/bin/env bash
nix build --impure --expr '
{ pkgs ? import <nixpkgs> {} }:
let
myEmacs = pkgs.emacs-nox;
emacsWithPackages = (pkgs.emacsPackagesFor myEmacs).emacsWithPackages;
in
emacsWithPackages (epkgs:
(with epkgs.elpaPackages; [ undo-tree ]))
'
E=./result/bin/emacs
cat <<'EOF' > test.el
(message "load-path has %s items" (length load-path))
(message "UNDO_TREE is installed?: %s" (package-installed-p (quote undo-tree)))
EOF
cat <<'EOF' > nested.el
(with-temp-buffer
(call-process
(expand-file-name invocation-name invocation-directory)
nil
(current-buffer)
nil
"-Q" ;; doesn't matter whether it's "-Q" or "-q"
"--batch"
"--load"
"test.el")
(message "NESTED:\n%s" (buffer-string)))
EOF
echo "======== Running directly: -q"
$E -q --batch --load test.el
echo -e "\n======== Running directly: -Q"
$E -Q --batch --load test.el
echo -e "\n======== Running as native compilation does it"
$E -q --batch --load nested.el
echo -e "\n======== Running as native compilation does it, but outer emacs with -Q - doesn't sanitize load-path"
$E -Q --batch --load nested.el
|
fixes NixOS#145302 NixOS#237855 emacsWithPackages wrapper script/`site-start.el` sanitize EMACSLOADPATH, to make nested emacs invocations independent of the package set specified in emacsWithPackages. But there are valid use cases when one needs to call nested emacs with the same package set. This includes built-in emacs functionality such as `restart-emacs` and async native compilations, and also external packages like `emacs-async` and `esup`. In all of these cases `invocation-directory`/`invocation-name` variables are being used to launch nested emacs. With this patch these variables will be populated to point to the emacsWithPackages wrapper executable, so that executing `(file-name-concat invocation-directory invocation-name)` will give a fully functional emacs again. `EMACSLOADPATH` sanitization was introduced by NixOS#106486, this behaviour stays unchanged. The reasoning was to be able to run different emacs executables without polluting their EMACSLOADPATH (as described here NixOS@23d4bfb). The only change is that invoking itself is again feasible (and that's what emacs actually expects).
fixes NixOS#145302 NixOS#237855 emacsWithPackages wrapper script/`site-start.el` sanitize EMACSLOADPATH, to make nested emacs invocations independent of the package set specified in emacsWithPackages. But there are valid use cases when one needs to call nested emacs with the same package set. This includes built-in emacs functionality such as async native compilations, and also external packages like `emacs-async` and `esup`. In all of these cases `invocation-directory`/`invocation-name` variables are being used to launch nested emacs. With this patch these variables will be populated to point to the emacsWithPackages wrapper executable, so that executing `(file-name-concat invocation-directory invocation-name)` will give a fully functional emacs again. `EMACSLOADPATH` sanitization was introduced by NixOS#106486, this behaviour stays unchanged. The reasoning was to be able to run different emacs executables without polluting their EMACSLOADPATH (as described here NixOS@23d4bfb). The only change is that invoking itself is again feasible (and that's what emacs actually expects). Co-authored-by: Lin Jian <[email protected]>
fixed by #361145 |
Describe the bug
When wrapping Emacs using emacsPackagesFor the invocation-directory will point to the wrong Emacs package. This means restarting Emacs from inside Emacs will result in a binary which doesn't see the additional packages to be started and initialization can fail.
Steps To Reproduce
nix-build the following derivation (ran out of disk space trying to build master, but looking at the source the issue seems to be the same, see additional info section). The issue happens both with and without emacs-overlay.
This will build a package my-emacs pulling in which-key and a package emacs-27.2 which is Emacs without the extra packages. The bin/emacs executable in my-emacs is a script setting up the environment so the wrapped executable will find which-key.
Run ./result/bin/emacs and press =C-h v invocation-directory= and check the resulting path. It should point inside the store path in target, but will be the path of the emacs-27.2 package.
Start a second Emacs instance from inside this one (variables need to be inserted by hand):
M-x, shell-command, {invocation-directory}{invocation-name}
in the second Emacs instance try to load the which-key package:
M-x, load-library, which-key
Expected behavior
The invocation-directory should point to the $my-emacs/bin/ instead of $emacs-27.2/bin in both Emacs instances.
Additional context
In nixpkgs I see wrapper.sh which does an exec without -a which seems to be where the original invocation name gets lost. This is the same on master. This will end up being the bin/emacs binary in the built derivation for my-emacs. bin/emacs in emacs-27.2 will be another wrapper doing another exec -a (I could not figure out where this was being generated, though).
I tried changing wrapper.sh using this patch but this was not successful, yet.
I think the second wrapper script in emacs-27.2 is overriding the invocation name, again.
Notify maintainers
@Stunkymonkey @alyssais @tadfisher (based on blame, not sure where the meta info is or if this is part of some specific package?)
Metadata
Please run
nix-shell -p nix-info --run "nix-info -m"
and paste the result.Maintainer information:
The text was updated successfully, but these errors were encountered: