haskell-nix
haskell-nix copied to clipboard
Recommend using callHackage
Reasons:
- no need to keep cabal and generated expressions in sync
- https://github.com/NixOS/cabal2nix/issues/217
So this is something I'm not yet sure about endorsing, but I might still mention it in the tutorial so that people are aware and can make an informed choice
The issues I have with this are:
- It leads to non-determinism in the build (since the package name and version do not suffice to fully determine the package, due to hackage permitting post-upload revisions)
- The build has to do work every time you run the build to compute the derivation
- "Import from derivation" still has some issues that need to be worked out, such as:
- https://github.com/NixOS/nix/issues/1148
- dry-runs doing work and failing (which is a very bad user experience)
- poor Hydra integration (now the Hydra evaluator needs to perform builds)
I actually prefer the two-phase cabal2nix
+ nix-build
distinction because this forces the user to explicitly opt in to potentially non-deterministic changes at controlled checkpoints (i.e. whenever they run cabal2nix
) and then they can trust in determinism for all other points in time
There's an alternative to using callHackage.
I use a bit of code like this https://github.com/expipiplus1/dotfiles/blob/master/nix-haskell-skeleton/default.nix to generate default.nix during evaluation time from the .cabal
file.
It still has some of the same drawbacks though, hydra has to build cabal2nix
before finishing evaluation (although this is cached, so not a big deal in practice) for example.
So actually I did more digging into callHackage
and it now has safeguards to ensure determinism so I would prefer to use it if possible. However, the next issue I ran into was that it just hung when I tried to use it and I haven't had a chance to investigate why yet
I would be interested in a example of usage for ´callHackage` or a link to some help that is not nix source code ;-)
@PierreR Considering callHackage
is a nix function I'm not sure how to help without writing nix code. But here's a simple example.
Assume you have a Haskell nix package that needs turtle
but the one in nixpkgs is too old. You could do something like this. (Note that for simplicity this does not use the full-blown override
mechanism, although that's probably what you'd want to do IRL.)
let
haskellPackages = (import <nixpkgs> {}).haskellPackages;
upgradedTurtle = haskellPackages.callHackage "turtle" "1.3.1" {};
in
haskellPackages.callPackage ./my-own-haskell-package.nix {
turtle = upgradedTurtle;
}
@Gabriel439 @expipiplus1 I'm working on getting that into Nixpkgs itself: https://github.com/NixOS/nixpkgs/pull/22191
@3noch Thanks (I just meant I would rather understand using the function from an example than from the code source of that function).
I am probably doing something obviously wrong but with this file I have got this error:
building path(s) ‘/nix/store/40w6k81a0yb9db64sv2wv63imra3cw2h-cabal2nix-language-puppet-1.3.5’
installing
sed: can't read /nix/store/aqg3rjr6qbabmb0nh9ph6k9ig6hfivxv-all-cabal-hashes-ee101d34ff8bd59897aa2eb0a124bcd3fb47ceec-src/language-puppet/1.3.5/language-puppet.json: No such file or directory
Any idea ?
@PierreR I'd wonder what your version of nixpkgs is. Probably should take this to #nixos
on IRC.
It is pinned with: export NIX_PATH=nixpkgs==https://github.com/NixOS/nixpkgs-channels/archive/9d0a9bc9d61f6e94d720486ddbe972af8547382d.tar.gz
It is from 2016-12-30T23:42:10+01:00. I will try with a more recent ref.
@PierreR Yah I'd try that first. callHackage
is new and when it was first introduced it had some issues (as @Gabriel439 pointed out). I had a discussion with the author and he ended up changing it.
As I said on #nixos
I did try with another more recent version (2017-01-24) with no luck. But I am wondering, maybe I need to wait for the next automatic Haskell package set update ? The version I want to fetch is fresh from today.
Yes that's the problem. You'll need to use the trick I'm adding in https://github.com/NixOS/nixpkgs/pull/22191 and get the source directly from GitHub or whathaveyou.
@3noch OK.Thanks for your help !
@Gabriel439 The latest nixpkgs-unstable
has haskellPackages.callCabal2nix
. With it you can do things like:
turtle = haskellPackages.callCabal2nix "turtle" (fetchFromGitHub {
owner = "Gabriel439";
repo = "Haskell-Turtle-Library";
rev = "f22ad5c35f910b11b833bbbbb08df212d5fde06c";
sha256 = "...";
}) {};
tried using callHackage in the referenced nix-build (postgrest) and it failed, worked with just command line cabal2nix
building path(s) ‘/nix/store/g7gzdj7bwjc0yg4jdg0fxw8gmfz0ckbz-cabal2nix-hasql-transaction-.5’
installing
sed: can't read /nix/store/aqg3rjr6qbabmb0nh9ph6k9ig6hfivxv-all-cabal-hashes-ee101d34ff8bd59897aa2eb0a124bcd3fb47ceec-src/hasql-transaction/.5/hasql-transaction.json: No such file or directory
curl: (3) <url> malformed
error: could not download /nix/store/aqg3rjr6qbabmb0nh9ph6k9ig6hfivxv-all-cabal-hashes-ee101d34ff8bd59897aa2eb0a124bcd3fb47ceec-src/hasql-transaction/.5/hasql-transaction.cabal
cabal2nix: nix-prefetch-url: createProcess: runInteractiveProcess: exec: does not exist (No such file or directory)
builder for ‘/nix/store/ccdz5xnnr4p8dd427wr3sydy7y03qr61-cabal2nix-hasql-transaction-.5.drv’ failed with exit code 1
error: build of ‘/nix/store/ccdz5xnnr4p8dd427wr3sydy7y03qr61-cabal2nix-hasql-transaction-.5.drv’ failed
@NotBrianZach callHackage
relies on all-cabal-hashes
which is frozen with a nixpkgs release. Most likely the package you want isn't available in that snapshot. You have two options: Override all-cabal-hashes
in your package set to a newer clone of all-cabal-hashes
or use something like haskellPackages.callCabal2nix "a-package" (pkgs.fetchFromGitHub {...}) {}
.
You also have a third option which may or may not work: Use a newer nixpkgs.
@3noch It is not quite clear what the first argument of callCabal2nix
is for ?
turtle = hlib.dontCheck(hlib.dontHaddock(hghc.callCabal2nix "turtle" (pkgs.fetchFromGitHub {
...
}) {};
henv = hghc.ghcWithPackages (p: with p; [turtle]);
What is the purpose of "turtle"
?
I am also asking because I have experienced some weird caching issue where nix is rebuilding the haskell package but ultimately somehow it is still used the old one in ghcWithPackages
@pradermecker It's used to give a better name to the store path.
If you updated links somewhere but did not update the SHA-256 hash, then that might be your problem.
@3noch Thanks for the info !
@3noch I don't see why this code fails with:
error: string ‘/nix/store/3ibw2qzxknyjd30zlw0l5yikwla6yivr-language-puppet-22d8fb4ee0ad833ca2f0790e3c473e7e49424232-src’ cannot refer to other paths, at /nix/store/9wx96zrrr6ixgns3k64isk0vdzc4yci8-nixpkgs-fff8cc79df5aa26e935f8ee30c06ef79368ad5dc-src/pkgs/development/haskell-modules/default.nix:92:25
The error points to https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/default.nix#L92
I am using this nixpkgs pointer:
{
"url": "https://github.com/NixOS/nixpkgs.git",
"rev": "fff8cc79df5aa26e935f8ee30c06ef79368ad5dc",
"date": "2017-03-20T19:03:20+01:00",
"sha256": "0jlnx75zri3gblzxb0jibllqclki0ykwn8d9zsp5p8yzyvn70j44",
"fetchSubmodules": true
}
Any idea ? Thanks ;-)
@PierreR Feel free to hop on #haskell or #nixos IRC. I'm eacameron.