Skip to content
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

Cabal hell inside of nix-shell #505

Closed
aVikingTrex opened this issue Jun 15, 2021 · 7 comments
Closed

Cabal hell inside of nix-shell #505

aVikingTrex opened this issue Jun 15, 2021 · 7 comments

Comments

@aVikingTrex
Copy link

New to nix entirely. Off the back of a fresh install of nix, I installed the following via "nix-env -i":

  • cabal-install
  • cabal2nix

I then followed these instructions:

  • cabal init
  • cabal2nix --shell . > shell.nix
  • nix-shell
  • cabal run

This results in the following:
$ cabal run


Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: nix-test-0.1.0.0 (user goal)
[__1] next goal: base (dependency of nix-test)
[__1] rejecting: base-4.14.1.0/installed-4.14.1.0 (conflict: nix-test =>
base^>=4.14.2.0)
[__1] skipping: base-4.15.0.0 (has the same characteristics that caused the
previous version to fail: excluded by constraint '^>=4.14.2.0' from
'nix-test')
[__1] rejecting: base-4.14.2.0, base-4.14.1.0, base-4.14.0.0, base-4.13.0.0,
base-4.12.0.0, base-4.11.1.0, base-4.11.0.0, base-4.10.1.0, base-4.10.0.0,
base-4.9.1.0, base-4.9.0.0, base-4.8.2.0, base-4.8.1.0, base-4.8.0.0,
base-4.7.0.2, base-4.7.0.1, base-4.7.0.0, base-4.6.0.1, base-4.6.0.0,
base-4.5.1.0, base-4.5.0.0, base-4.4.1.0, base-4.4.0.0, base-4.3.1.0,
base-4.3.0.0, base-4.2.0.2, base-4.2.0.1, base-4.2.0.0, base-4.1.0.0,
base-4.0.0.0, base-3.0.3.2, base-3.0.3.1 (constraint from non-upgradeable
package requires installed instance)
[__1] fail (backjumping, conflict set: base, nix-test)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: base, nix-test

Are these instructions not correct? What do I need to do to get nix and cabal to play nice? I should mention that there is not a locally installed cabal on my machine.
Thanks in advance!

@expipiplus1
Copy link
Contributor

Welcome!

The problem here isn't really cause by Nix. Rather it's because:

  • base 4.14.1 is installed (and base version can't be changed)
  • nix-test requires base >= 4.14.2

To solve the immediate problem: Are you able to relax the lower bound on base in nix-test?. Currently nixpkgs provides ghc 8.10.4 (and hence base 4.14.1) by default.


Here's what I would do for running cabal init and starting a new project:

  • nix-shell -p ghc cabal-install To have access to GHC and cabal-install

    • cabal init in this shell
  • Put the following in default.nix. This will automatically call cabal2nix
    for you when you enter the shell or build the package, saving you the hassle
    of having to keep any .nix file up to date with your package dependencies
    manually.

    { pkgs ? import <nixpgks> { } }:
    
    pkgs.haskellPackages.developPackage {
      # There are several more options one can use here detailed here:
      # https://github.com/nixos/nixpkgs/blob/35832045ceab6954f4a3116d77f2a06c72e2424c/pkgs/development/haskell-modules/make-package-set.nix#L222-L249
      root = ./.;
    
      # Disable hoogle to avoid bumping into https://github.com/NixOS/nixpkgs/issues/82245
      withHoogle = false;
    }
  • Enter this shell and develop as usual with GHC and your package dependencies.


Hoogle support

Currently hoogle database generation has a bug preventing it from working when the package has only builtin dependencies (base, text, etc...). (NixOS/nixpkgs#82245). Once you have added a non-builtin dependency (or are using a nixpkgs revision with NixOS/nixpkgs#127028 or an alternate fix) you can remove the withHoogle = false line and perform the following.

  • In this shell you can also run hoogle server --local to run a Hoogle server
    for browsing documentation for the packages in the shell.
    • For a hoogle server which automatically reloads on changes to the .cabal
      file one can do something like echo *.cabal | entr -r -- nix-shell --run 'hoogle server --local'. The entr tool is available in nixpkgs.

As an aside, did you install GHC 8.10.5 with something other than Nix? 8.10.5
currently isn't packaged for Nix, but your cabal init seems to be using its
associated base version. To enter a shell with just GHC you can run nix-shell -p ghc.

@aVikingTrex
Copy link
Author

Thank you so much for such a detailed reply!
I do in fact have ghc 8.10.5 already on the machine. It didn't even occur to me that it could be the culprit. Sorry!
If I plan on mainly using nix for environments in future, is it better to simply remove ghc from this machine or can I safely keep it, and do what you have done and provide nix-shell its own version of ghc? Will there still be a collision of base versions?
Also, in order to actively develop inside of nix-shell I have installed direnv to have access to emacs and my config for that. Does that change any of your recommendations?

@expipiplus1
Copy link
Contributor

expipiplus1 commented Jun 17, 2021

Thank you so much for such a detailed reply!

No problem, happy to help. Feel free to join us in the Nix-Haskell Matrix room too.

I do in fact have ghc 8.10.5 already on the machine. It didn't even occur to me that it could be the culprit. Sorry!

I guess it was an unfortunate interaction between cabal init and the new version of GHC, had it been 8.10.4 then I don't think this would have been a problem.

If I plan on mainly using nix for environments in future, is it better to simply remove ghc from this machine or can I safely keep it, and do what you have done and provide nix-shell its own version of ghc? Will there still be a collision of base versions?

Probably no point keeping this GHC around, as any nix-provisioned Haskell environment will put its own GHC there anyway. I don't think that keeping it around will cause any problems (aside from the cabal init one), there might be some unforeseen interactions though, and it's really just wasted disk space.

Also, in order to actively develop inside of nix-shell I have installed direnv to have access to emacs and my config for that. Does that change any of your recommendations?

I've never used direnv I'm afraid, so can't comment authoritatively. I believe that any nix shell environment can be used with direnv though, but I don't know the details.

@sternenseemann
Copy link
Member

I've never used direnv I'm afraid, so can't comment authoritatively. I believe that any nix shell environment can be used with direnv though, but I don't know the details.

Most notably, direnv can't run setup hooks which do extra environment setup in nix-shell. This doesn't necessarily mean that what you want doesn't work, but it is important to note that direnv behaves differently than a nix-shell in case you run into trouble.

@aVikingTrex
Copy link
Author

I guess my followup question is how do people typically develop inside of nix-shell? I usually develop using emacs with lsp-mode ect and it doesnt seem to work properly inside of nix-shell without direnv.
I would gladly reduce the amount of tools required by removing direnv if I am simply missing an obvious step.

@sternenseemann
Copy link
Member

No, direnv is probably the best call for editor integration. The environment is probably best set up with something like shellFor or developPackage (mentioned above), which also allows including haskell-language-server into the shell environment.

@aVikingTrex
Copy link
Author

Thank you both very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants