[Nix-dev] nix-shell for a custom haskell library

Peter Simons simons at cryp.to
Tue Jun 2 11:21:40 CEST 2015


Hi Dmitry,

 > The way I've used nix-shell for some haskell packages before was
 > something like that:
 >
 >   nix-shell -p '(haskellPackages.callPackage ./default.nix { })' --command 'builtExecutable'

I see no reason why that command shouldn't continue to work just as
before. If your "default.nix" uses valid syntax, etc., then this
approach should work just fine.


 > And here is an example of one of that old-way-haskell-packages
 > expressions:
 >
 > { pkgs ? (import <nixpkgs> {}) }:
 >
 > let biegunka = import ./biegunka.nix {}; in
 >
 > pkgs.haskellPackages.cabal.mkDerivation (self: {
 >   [...]
 > })
 >
 > Nowadays, there is no more `haskellPackages.cabal.mkDerivation`.

Right, there is not. You'll have to adapt the build instructions for the
new code. The easiest way to do that is to just generate the expression
with cabal2nix. For example, let's build and run the program "hlint":

 $ nix-shell -p "haskellPackages.callPackage ( $(cabal2nix cabal://hlint) ) {}" --command "hlint --version"
 HLint v1.9.21, (C) Neil Mitchell 2006-2015

Alternatively, you can also build the source code with "cabal":

  $ nix-env -iA haskellPackages.cabal-install
  $ nix-shell "<nixpkgs>" -A haskellPackages.hlint.env
  [nix-shell:/tmp]$ cabal get hlint-1.9.21
  [nix-shell:/tmp]$ cd hlint-1.9.21
  [nix-shell:/tmp/hlint-1.9.21]$ cabal run hlint -- --version
  Package has never been configured. Configuring with default flags. If this
  fails, please run configure manually.
  Resolving dependencies...
  Configuring hlint-1.9.21...
  [... lots of compiler messages omitted ...]
  Linking dist/build/hlint/hlint ...
  Running hlint...
  HLint v1.9.21, (C) Neil Mitchell 2006-2015

If you want to go all out, you can even build the package in a *pure*
environment:

  $ nix-shell --pure "<nixpkgs>" -A haskellPackages.hlint.env
  [nix-shell:/tmp]$ cd /tmp/hlint-1.9.21
  [nix-shell:/tmp/hlint-1.9.21]$ runhaskell Setup.hs build
  [... lots of compiler messages omitted ...]
  In-place registering hlint-1.9.21...
  Preprocessing executable 'hlint' for hlint-1.9.21...

  [nix-shell:/tmp/hlint-1.9.21]$ dist/build/hlint/hlint --version
  HLint v1.9.21, (C) Neil Mitchell 2006-2015

If you want to do this stuff with a package that's not registered on
Hackage, then the command "cabal2nix --shell" can generate a suitable
environment for you:

  $ cd ~/src/my-package
  $ cabal2nix --shell . >shell.nix
  $ nix-shell --command "cabal run my-package -- --my-flag"

If you have cabal2nix version 20150531 or later from the current Nixpkgs
"master" branch, then you can even use "nix-build" on that generated
shell.nix file:

  $ nix-build shell.nix
  [... lots of compiler messages omitted ...]
  $ result/bin/my-package --my-flag

There's half a dozen ways to accomplish what you want, you just have to
pick the one that's most convenient for you.


 >> nix-shell --command "cabal configure && cabal build".
 >
 > Yeah, but the problem with this approach is some kind of lack of an
 > isolation, since the path where the packages are being installed into
 > is shared:
 >
 >   /Users/m/.ghc/x86_64-darwin-7.10.1/package.conf.d
 >      engine-io-1.2.6

cabal configure accepts a "--prefix" argument that let's you put the
installed files into any location you please. Besides, it's usually
unnecessary to install the programs in the first place. You can run them
in-place with "cabal run", or you simply execute the binary after the
build step directly from the dist/build/ directory.

Best regards,
Peter



More information about the nix-dev mailing list