Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NixOS and ghc-mod - Module not found

I'm experimenting a problem with the interaction between the ghc-mod plugin in emacs, and NixOS 14.04. Basically, once packages are installed via nix-env -i, they are visible from ghc and ghci, recognised by haskell-mode, but not found by ghc-mod.

To avoid information duplication, you can find all details, and the exact replication of the problem in a VM, in the bug ticket https://github.com/kazu-yamamoto/ghc-mod/issues/269

like image 943
meditans Avatar asked Jun 15 '14 09:06

meditans


1 Answers

The current, default, package management set up for Haskell on NixOS does work will with packages that use the ghc-api, or similar (ghc-mod, hint, plugins, hell, ...) run time resources. It takes a little more work to create a Nix expression that integrates them well into the rest of the environment. It is called making a wrapper expression for the package, for an example look at how GHC is installed an operates on NixOS.

It is reasonable that this is difficult since you are trying to make a install procedure that is atomic, but interacts with an unknown number of other system packages with their own atomic installs and updates. It is doable, but there is a quicker work around.

Look at this example on the install page on the wiki. Instead of trying to create a ghc-mod package that works atomically you weld it on to ghc so ghc+ghc-mod is an atomic update.

I installed ghc+ghc-mod with the below install script added to my ~/.nixpkgs/nixpkgs.nix file.

hsEnv = haskellPackages.ghcWithPackages (self : [                            
  self.ghc                                                                   
  self.ghcMod                                                                
  # add more packages here                                                   
]);

Install package with something like:

nix-env -i hsEnv

or better most of the time:

nix-env -iA nixpkgs.haskellPackages.hsEnv

I have an alias for the above so I do not have to type it out every time. It is just:

nixh hsEnv

The down side of this method is that other Haskell packages installed with nix-env -i[A] will not work with the above installation. If I wanted to get everything working with the lens package then I would have to alter the install script to include lens like:

hsEnv = haskellPackages.ghcWithPackages (self : [                            
  self.ghc                                                                   
  self.ghcMod 
  self.lens                                                               
  # add more packages here                                                   
]);

and re-install. Nix does not seem to use a different installation for lens or ghc-mod in hsEnv and with the ghc from nix-env -i ghc so apparently only a little more needs to happen behind the scenes most of the time to combine existing packages in the above fashion.

ghc-mod installed fine with the above script but I have not tested out its integration with Emacs as of yet.

Additional notes added to the github thread

DanielG:

I'm having a bit of trouble working with this environment, I can't even get cabal install to behave properly :/ I'm just getting lots of errors like:

With Nix and NixOS you pretty much never use Cabal to install at the global level

  • Make sure to use sandboxes, if you are going to use cabal-install. You probably do not need it but its there and it works.
  • Use ghcWithPackages when installing packages like ghc-mod, hint, or anything needs heavy runtime awareness of existing package (They are hard to make atomic and ghcWithPackages gets around this for GHC).
  • If you are developing install the standard suite of posix tools with nix-env -i stdenv. NixOS does not force you to have your command line and PATH cultured with tools you do not necessarily need.
  • cabal assumes the existence a few standard tools such as ar, patch(I think), and a few others as well if memory services me right.

If you use the standard install method and/or ghcWithPackages when needed then NixOS will dedup, on a package level (If you plot a dependency tree they will point to the same package in /nix/store, nix-store --optimise can always dedup the store at a file level.), many packages automatically unlike cabal sandboxes.


Response to comment

[carlo@nixos:~]$ nix-env -iA nixos.pkgs.hsEnv

installing `haskell-env-ghc-7.6.3'
these derivations will be built:
  /nix/store/39dn9h2gnp1pyv2zwwcq3bvck2ydyg28-haskell-env-ghc-7.6.3.drv
building path(s) `/nix/store/minf4s4libap8i02yhci83b54fvi1l2r-haskell-env-ghc-7.6.3'
building /nix/store/minf4s4libap8i02yhci83b54fvi1l2r-haskell-env-ghc-7.6.3
collision between `/nix/store/1jp3vsjcl8ydiy92lzyjclwr943vh5lx-ghc-7.6.3/bin/haddock' and `/nix/store/2dfv2pd0i5kcbbc3hb0ywdbik925c8p9-haskell-haddock-ghc7.6.3-2.13.2/bin/haddock' at /nix/store/9z6d76pz8rr7gci2n3igh5dqi7ac5xqj-builder.pl line 72.
builder for `/nix/store/39dn9h2gnp1pyv2zwwcq3bvck2ydyg28-haskell-env-ghc-7.6.3.drv' failed with exit code 2
error: build of `/nix/store/39dn9h2gnp1pyv2zwwcq3bvck2ydyg28-haskell-env-ghc-7.6.3.drv' failed

It is the line that starts with collision that tells you what is going wrong:

collision between `/nix/store/1jp3vsjcl8ydiy92lzyjclwr943vh5lx-ghc-7.6.3/bin/haddock' and `/nix/store/2dfv2pd0i5kcbbc3hb0ywdbik925c8p9-haskell-haddock-ghc7.6.3-2.13.2/bin/haddock' at /nix/store/9z6d76pz8rr7gci2n3igh5dqi7ac5xqj-builder.pl line 72.

It is a conflict between two different haddocks. Switch to a new profile and try again. Since this is a welding together ghc+packages it should not be installed in a profile with other Haskell packages. That does not stop you from running binaries and interrupters from both packages at once, they just need to be in their own name space so when you call haddock, cabal, ghc, there is only one choice per profile.

If you are not familiar with profiles yet you can use:

nix-env -S /nix/var/nix/profiles/per-user/<user>/<New profile name>

The default profile is either default or channels do not which one it will be for your set up. But check for it so you can switch back to it later. There are some tricks so that you do not have to use the /nix/var/nix/profiles/ directory to store you profiles to cut down on typing but that is the default location.

like image 91
Davorak Avatar answered Oct 07 '22 23:10

Davorak