Install multiple versions of a package, each with its own binary

Hi,

I’m trying to install 2 versions of Emacs in my system:

  1. The default Emacs package in nixpkgs
  2. A locally cloned and modified Emacs

I have created an overlay for this, however, it still installs it as ‘emacs’.
How do I set it up such that each installation will have its own separate binary (emacs and emacs-localbuild)?

Here is the overlay:

self: super:

let
  nixos = import <nixpkgs/nixos> {};
  unstable = nixos.pkgs.unstable;
in {
  emacs-localbuild = (unstable.emacs.override {
    nativeComp = true;
    srcRepo = true;
  }).overrideAttrs (oldAttrs: rec {
    version = "localbuild";

    src = /ssd/emacs;
  });
}

Thanks!

1 Like

It depends a bit on the derivation I guess. If it already uses makewrapper or has a custom install phase you could probably just modify those.

If it leans on make and make install, you could probably just mv $out/bin/emacs to the path you want during fixup phase?

1 Like

Thanks for pointing me in the right direction. Creating symlinks during post fixup works.

    postFixup = oldAttrs.postFixup + ''
      ln -s "emacs" "$out/bin/emacs-localbuild"
      ln -s "emacsclient" "$out/bin/emacsclient-localbuild"
    '';

However I am having collisions on the 2 versions of the package.
I think I’ll just do nix-shell -p emacs or nix-shell -p emacs-localbuild as needed.

What’s the exact error/problem?

I have done similar things using mkShellScriptBin which just contains sth like exec ${experimentalEmacs}/bin/Emacs "$@", but it might be simpler to nix-build it and start it using ./bin/emacs

1 Like

What I did was setup 2 Emacs overlays – 1st for the default package and the 2nd one for my locally built code.

Here’s the error being thrown, I’m guessing this is the fixup phase trying to move the Emacs Info files to /share.

error: collision between `/nix/store/y1kiwml5vajb9qcg543vg6s1af6i4wb2-emacs-localbuild/share/info/emacs.info.gz' and `/nix/store/kpbfkxqb4bjmvzn0had5w2m70x89n394-emacs-27.2/share/info/emacs.info.gz'
builder for '/nix/store/yam0y96a5ys8vm30aa1v9f9gly980zi9-home-manager-path.drv' failed with exit code 25
1 Like

That looks like the real file conflict. Nix has detected that you have multiple packages which provide emacs.info.gz and stops, because it’s not possible to create an environment with those packages.

If you want to have both versions available without switching it in the configuration.nix, you will have to wrap one of them in a script…

Try to replace one of the packages with sth like this:

(wrieShellScriptBin "my-emacs" ''
   exec "${my-emacs}/bin/emacs" "$@"
'')

Then you can start it using my-emacs.

This avoids the collision because the derivation contains only a shell script, the rest of my-emacs is not brought into the environment directly

2 Likes

You could also presumably use the fixup to delete the conflicting files in one of the two outputs (assuming you don’t need them).

Thanks a lot, this works!

1 Like