last updated 2024-01-29 for nix 2.13 - 2.18, nixos 23.05 - 23.11
The Nitpicks Page
Sometimes I skip over some little details to make things feel more conceptually elegant or whatever. Usually these details are too irrelevant to the issue at hand, or too out of scope of the proficiency level the document was intended for, that they don't even deserve an infobox aside.
However, I don't ever want to mislead, so this page is for making those kinds of details clear!
If you have any questions, complaints, or suggestions, contact us!
Reproducibility of Derivations
Nix certainly makes it easier to specify a build that produces the
same output on any system of a given platform, but it isn't magic. For
instance, you can have a working derivation that runs
echo $RANDOM >$out
to produce its output, with no complaint from
Nix.
The extensional model (the one I describe, where output paths are derived from their inputs), is an obvious and elegant one for the reason that knowing output paths a priori is convenient for binary caching and for avoiding path rewriting after the fact. However, it makes no attempt to mitigate this problem: my random-number derivation will produce an object with the same path but different contents on every system.
Given well-behaved builds and trusted substituters, this caveat is not normally a problem. I'll leave more insidious, less obvious forms of build nondeterminism to your imagination. For fun, you can check how much nondeterminism still exists in NixOS isos at this page!
If you want to learn about the experimental mitigation for this problem, wherein output paths are rewritten to be content-addressed, and thus nondeterministic builds do receive nondeterministic output paths, see The purely functional software deployment model, chapter 6 or Nix RFC 0062, Content-addressed paths.
derivationStrict
Actually, derivation
isn't the barest primitive for producing
store derivations from inside Nix. It's just a
wrapper function around the real primop,
derivationStrict
.
In essence, the wrapper just takes the output of derivationStrict
(which only produces a set containing drvPath
and attributes from
output-name to output-path) and massages it into the more featureful output I
describe in Writing Packages.
There is no reasonable circumstance where you would need to know this or call
derivationStrict
yourself (unless you happen to be making a Nix
language implementation). It's just an interesting tidbit :)