Hi! I’m using Nixpkgs 21.11.337967 and in a side project I thought I would try to use the optics
library. The most recent version is optics
0.4.2
which depends on optics-th
0.4.1
and optics-core
0.4.1
. This version of Nixpkgs has optics
pointing at an older version but optics_0_4
pointing to a newer version. I’m trying to override each of these dependencies in a way that their dependees find them correctly. I’m trying to write targeted overrides rather than just copying and replacing the whole derivations. So far I haven’t gotten it to work.
Here’s a simplified default.nix
that shows more-or-less what I’m stuck on:
{ pkgs ? import <nixpkgs> {}, compiler ? "ghc921" }:
let
hPackages = pkgs.haskell.packages.${compiler}.override (old: {
overrides = pkgs.lib.composeExtensions old.overrides (self: super: rec {
optics-th = (pkgs.haskell.lib.overrideCabal super.optics-th_0_4 (old: {
version = "0.4.1";
sha256 = "05zxljfqmhr5if7l8gld5s864nql6kqjfizsf1z7r3ydknvmff6p";
})); #.overrideScope (_: _: {});
optics-core = (pkgs.haskell.lib.overrideCabal super.optics-core_0_4 (old: {
version = "0.4.1";
sha256 = "16ll8829g8v5g6gqdcfj77k6g4sqpmpxbda9jhm4h68pycay4r6a";
}));
});
});
in
hPackages.optics-th
This file does not build:
Configuring optics-th-0.4.1...
Setup: Encountered missing or private dependencies:
optics-core >=0.4.1 && <0.5
So, clearly my override of the src
for optics-th
is working fine, but its references in libraryHaskellDependencies
are not referring to optics-core
. But… shouldn’t it? The Haskell package set uses a fixed-point combinator to create a package set that is mutually recursive, and I guessed/hoped that those references would refer to the final “self” set after all the overrides. It seems like here, that isn’t happening.
In the end, I found that I could get it to pick up my modified versions of dependencies by slapping .overrideScope (_: _: {})
at the end of each overridden derivation. But I don’t really understand why.
I tried to debug a little further but wasn’t really able to make headway. Looking at the definition of optics-th
in hackage-packages
:
"optics-th_0_4" = callPackage
({ mkDerivation, base, containers, mtl, optics-core, tagged
, template-haskell, th-abstraction, transformers
}:
mkDerivation {
pname = "optics-th";
version = "0.4";
sha256 = "1qddzwhzlhhp1902irswjj18aa5ziavn4klhy7najxjwndilb55y";
libraryHaskellDepends = [
base containers mtl optics-core template-haskell th-abstraction
transformers
];
testHaskellDepends = [ base optics-core tagged ];
description = "Optics construction using TemplateHaskell";
license = lib.licenses.bsd3;
hydraPlatforms = lib.platforms.none;
}) {};
I tried debugging this a little further using something like this:
libraryHaskellDepends = pkgs.lib.debug.traceSeq (builtins.elemAt old.libraryHaskellDepends 4) old.libraryHaskellDepends;
… in the overridden definition of optics-th
. Here we see that 4 should correspond to the template-haskell
dependency. When I try to build this, I see the trace message trace: null
. If I change the 4 to 3 and add .name
after the parentheses, I see the trace message trace: optics-core-0.4
. Hang on a second – optics-th
depends on optics-core
– shouldn’t this be optics-core-0.3.0.1
? (It is if I change the call to overrideCabal
to refer to super.optics-th
instead of super.optics-th_0_4
.) Also, if I add template-haskell = super.template-haskell_2_18_0_0;
to my overridden set, then the 3rd dependency stops being null and starts being template-haskell-2.18.0.0
. Why? It seems like the mutual recursion is doing something since it picks up the new version of template-haskell
, but I’m clearly lost as to why it isn’t picking up the version I want of optics-core
.
Any thoughts on this topic, or more generally how to debug this kind of thing, would be greatly appreciated! Thanks!