I’m having trouble getting overlays to work in nested flakes. Let’s say I have a flake named systemFlake, which is a flake describing my system, which uses a flake named flakeB, which in turn needs a flake named flakeC.
flakeC exposes its derivation through an overlay, like so:
{
outputs = { self, ... }: {
overlay = final: prev: final.callPackage ./pkg.nix {};
};
}
(pkg.nix
is a function that takes some parameters that are present in nixpkgs)
Now I want to use this flake from flakeB, which also exposes an overlay, just like flakeC:
{
inputs.flakeC.url = "...";
outputs = { self, flakeC, ... }: {
overlay = final: prev: final.callPackage ./pkg.nix {};
};
}
This time, the function in pkg.nix
also takes a parameter flakeC
. But this attr is not in final
, unless the caller (systemFlake) includes flakeC in its overlays, which I don’t want. Basically I’d like systemFlake to look like this:
{
inputs.flakeB.url = "...";
outputs = { self, nixpkgs, flakeB, ... }:
let
pkgs = import nixpkgs { overlays = [ flakeB ]; };
in {
nixosConfigurations.foobar.systemPackages = [ pkgs.flakeB ];
};
}
But this results in an error in flakeB since flakeB’s pkg.nix
is called without the required argument flakeC.
I thought of 2 solutions:
- Don’t use overlays. I don’t think that’s a good solution since the flakes manpage states that (in the section about
follows
): “It is worth noting, however, that it is generally not useful to eliminate transitive nixpkgs flake inputs in this way. Most flakes provide their functionality through Nixpkgs overlays or NixOS modules, which are composed into the top-level flake’s nixpkgs input; so their own nixpkgs input is usually irrelevant.” - Use
pkgs.extend
orpkgs.appendOverlays
in flakeB to add flakeC’s overlay tofinal
. I don’t think that’s a good solution since the Nixpkgs manual states that “although it is often preferable to avoid these functions, because they recompute the Nixpkgs fixpoint, which is somewhat expensive to do.”
Do you see other solutions? What’s the recommended way to do this?