I’m trying to compute the build time closure of a derivation, outside of Nix. Slightly misleading title, because I think I’ve done most of the work, just ended up stuck on some details
I naively assumed parsing a derivation and then recursively gathering all inputDrvs
and inputSrcs
would suffice, but that doesn’t seem to hold - at least not for my nixos-system
derivation. Using this strategy I can discover 7752 out of 7790 paths compared to nix-store -qR
of my system derivation - so there are 38 missing.
The difference seems to stem from the store path for modules.xml
(nixpkgs src) which is generated using builtins.toFile
. Importantly, this file contains XML includes, which explains the dependency:
$ nix why-depends /nix/store/yb71ygc8dpxnkp64vdar1wazjf5wjbn7-modules.xml /nix/store/7l34sk54sjdlh7xcivrmj8gs312xfirg-pict-rs.xml
/nix/store/yb71ygc8dpxnkp64vdar1wazjf5wjbn7-modules.xml
╚═══/: …/>.<xi:include href="/nix/store/7l34sk54sjdlh7xcivrmj8gs312xfirg-pict-rs.xml" />.<xi:include hre…
=> /nix/store/7l34sk54sjdlh7xcivrmj8gs312xfirg-pict-rs.xml
If I query the nix-store for requisites of modules.xml
I find all 38 missing paths:
$ nix-store -qR /nix/store/yb71ygc8dpxnkp64vdar1wazjf5wjbn7-modules.xml
/nix/store/07fi8dm3inmsbxhnydzjl0jshw8346hn-trezord.xml
/nix/store/0g8yl6sbi4knqfi8n48f06v2vyx31770-yggdrasil.xml
/nix/store/0nxlsrqhghky7v0shfsld98mlcfbvqrx-borgbackup.xml
...
Reading Eelco’s PhD thesis to figure out whether this is intended leads me to believe it is (because by definition all recursive references are part of a closure and they don’t necessarily have to be in any derivation inputSrcs), but I remain puzzled by the fact that this is the only occurrence (in my system closure) of a dependency not reachable by only parsing derivations - it requires outside knowledge of the dependency (e.g. at evaluation time, which is how I believe Nix handles it).
Does this make sense?
Am I missing anything that does imply modules.xml
should be built from a derivation instead (which would solve my problem at least for my current system derivation)?
What’s the easiest way to figure out these missing dependencies? I managed to come up with either scanning all inputs for unknown store paths (slow) or querying the Nix store database (which keeps a table of references), just to get the last handful of paths…