How is fixed point used for overriding nixpkgs packages?

Nix Pills | Nix & NixOS says

17.3. Fixed point

nix-repl> fix = f: let result = f result; in result
nix-repl> pkgs = self: { a = 3; b = 4; c = self.a+self.b; }
nix-repl> fix pkgs
{ a = 3; b = 4; c = 7; }

17.3.1. Overriding a set with fixed point

Given that self.a and self.b refer to the passed set and not to
the literal set in the function, we’re able to override both a and
b and get a new value for c :

nix-repl> overrides = { a = 1; b = 2; }
nix-repl> let newpkgs = pkgs (newpkgs // overrides); in newpkgs
{ a = 3; b = 4; c = 3; }
nix-repl> let newpkgs = pkgs (newpkgs // overrides); in newpkgs // overrides
{ a = 1; b = 2; c = 3; }

In the first case we computed pkgs with the overrides, in the second
case we also included the overriden attributes in the result.

17.4. Overriding nixpkgs packages

We’ve seen how to override attributes in a set such that they get recursively picked by dependant attributes. This approach can be
used for derivations too, after all nixpkgs is a giant set of
attributes that depend on each other.

To do this, nixpkgs offers config.packageOverrides . So nixpkgs
returns a fixed point of the package set
, and packageOverrides is
used to inject the overrides
.

Create a config.nix file like this somewhere:

{
  packageOverrides = pkgs: {
    graphviz = pkgs.graphviz.override { withXorg = false; };
  };
}

Now we can build e.g. asciidoc-full and it will automatically use the
overridden graphviz:

nix-repl> pkgs = import <nixpkgs> { config = import ./config.nix; }
nix-repl> :b pkgs.asciidoc-full

Note how we pass the config with packageOverrides when importing
nixpkgs . Then pkgs.asciidoc-full is a derivation that has
graphviz input
( pkgs.asciidoc is the lighter version and doesn’t
use graphviz at all).

Since there’s no version of asciidoc with graphviz without X support
in the binary cache, Nix will recompile the needed stuff for you.

17.6. Conclusion

Nix applications will depend on specific versions of libraries, hence
the reason why we have to recompile asciidoc to use the new graphviz
library.

The newly built asciidoc will depend on the new graphviz, and old asciidoc will keep using the old graphviz undisturbed.

What does it mean by “override attributes in a set such that they get recursively picked by dependant attributes”? Could you explain that in terms of the example in 17.3.1?

What does it mean by “nixpkgs returns a fixed point of the package set”?

  • Isn’t a fixed point something belonging to a function, and the package set isn’t a function?

  • Why does nixpkgs return a fixed point? Is nixpkgs something similar to the example let newpkgs = pkgs (newpkgs // overrides); in newpkgs in 17.3.1.?

What does it mean by “packageOverrides is used to inject the overrides”?

Why “Then pkgs.asciidoc-full is a derivation that has graphviz input”?

Why “The newly built asciidoc will depend on the new graphviz”, and “old asciidoc will keep using the old graphviz undisturbed”?

Thanks.

1 Like

The documentation on how fixed-point computation in Nixpkgs works has never been great. @infinisil @roberth and me recently put quite some effort in clarifying lib.fixedPoints.fix, and I think by now it’s a good starting point to answer your questions. It’s obviously very much incomplete though. There’s also intermittent work going into better documenting and explaining overlays and overrides, but it will take a while to materialise.

1 Like

can you or someone try to reply to my questions?