How to override GHC core library in Haskell package

Is there an easy way to override a GHC core library when building a Haskell package?

For instance, the current GHC-8.6.5 package set uses bytestring-0.10.8.2:

$ nix-shell -p haskell.compiler.ghc865
$ ghc-pkg list # within nix-shell
/nix/store/5adkvmak1j42pxpbhpjq33p16g0588a4-ghc-8.6.5/lib/ghc-8.6.5/package.conf.d
...
    bytestring-0.10.8.2
...

I’d like to build a Haskell package linking to bytestring-0.10.8.1 instead.

I came up with something like the following:

This seems relatively complicated. I’m wondering if there is an easier way to do this?

Here are two parts I don’t really like:

  1. Having to pass a constraint to every package to force the version of bytestring I want, even if the package doesn’t use bytestring:

    https://gist.github.com/cdepillabout/a1b7226063f7aa57878059f9a3c638b4#file-example-nix-L25-L48

    I might be able to clean this up a little bit by checking if the package actually depends on bytestring, but it would be nice to completely handle this sort of thing in Nix code. Maybe doing something similar to stack and hiding all packages by default, and only enabling those explicitly asked for by the user.

  2. Having to override all GHC core packages that use bytestring is annoying:

    https://gist.github.com/cdepillabout/a1b7226063f7aa57878059f9a3c638b4#file-example-nix-L50-L60

    I understand why this is needed, but it would be nice if something like this could happen automatically (somehow).

Maybe someone like @domenkozar, @peti, or @matthewbauer would have a good idea of an easier way to do this.

The easiest way is to copy-paste https://github.com/NixOS/nixpkgs/blob/872122af438899db825c7f7fbec8879372c7357e/pkgs/development/haskell-modules/default.nix#L25 and leave out compilerConfig.

That’s how stack2nix works.

https://input-output-hk.github.io/haskell.nix/ takes a different approach and allows overriding core packages, while you can tell it not to.

2 Likes

@domenkozar Thanks for this response.

I guess the problem with doing similarly to how stack2nix works is that in the nixpkgs Haskell stuff, packages like binary, text, bytestring, etc aren’t actually defined anywhere. So even if I left out compilerConfig, I’d still have to go an define them somewhere (even if I just set them to null).

The other problem is what to do if I want to use an earlier version of one of the core libraries. The nixpkgs Haskell generic builder doesn’t hide any of core GHC packges, so if I try to pass an earlier version of one of the core packages, it often gets silently ignored.

For instance, if the GHC core package set contains bytestring-0.10.8.2, but I want to use bytestring-0.10.8.1, I need to add a constraint everywhere that forces Cabal to actually use it:

I was hoping there was some sort of easier way around this, but I guess not.

I think your idea of using stack2nix or haskell.nix is probably the easiest way forward for people that want to override the GHC core packages.