How does Nix compute runtime dependencies for commands like nix-copy-closure and nix copy?
Reading the Nix Manual, it appears to say that runtime dependencies are computed when needed, by scanning output paths for other /nix/store/* paths.
I have a couple questions about this:
Is the above explanation correct? This information is computed on-the-fly, and not present in the .drv file, correct? Can anyone point out the place in the Nix source code where this scanning step takes place?
There are a couple commands I know of to let you easily inspect the runtime (or build-time) closure:
However, are there any tools that show which files in a given output path have which runtime dependencies? (edit: err, yes, there is: nix why-depends. See the next question where I show using this…)
However, is there any general advice for figuring out why a given binary contains a /nix/store path? (I imagine the answer to this will depend on what type of binary it is…)
If I know that a given runtime dependency is not actually needed (so it can be excluded from the closure), is there any way to tell nix copy or nix-copy-closure to exclude it?
I imagine I can modify the original derivation to remove unneeded /nix/store/ path in its output files, but I am just wondering what other options I have here.
When writing a derivation, is there any way to force a runtime dependency?
I’ve seen /nix/store/*/nix-support/propagated-build-inputs files. Is that effectively what these files are for?
I suggest reading the nix-pills which explain exactly these kinds of detail. If you still have questions after reading them, I suggest asking again in this discourse: I think that one question per thread would be easier to answer.
You kind of answered this yourself. As long a nix can read a /nix/store path in the outputs, it will consider it a runtime dependency. Nix can’t know about these paths til after it builds a package, so this is why why-depends will usually build the package before giving output.
The out paths from the inputs is known, and nix can assert that the paths exist.
It would probably be located in the nix store realize code, but I’m not super familiar with the code base.
nix-store --query --references for direct runtime dependencies nix-store --query --requisites for all runtime dependencies
if you pass a .drv, you will get the related build dependencies.
nix why-depends and grep are all that I’m aware of.
You can use disallowedReferences or disallowedRequisites when creating your derivation to prevent this Introduction
As long as the store path appears in the out path, it will be a runtime dependency.
$ sqlite3 /nix/var/nix/db/db.sqlite
sqlite> select id from ValidPaths where path = "/nix/store/jr56bx8a41h1x0wm7ih2mic5i3cjfcm1-coreutils-8.32";
48929
sqlite> select path from ValidPaths where id in (select reference from Refs where referrer = 48929);
/nix/store/gafigwfaimlziam6qhw1m8dz4h952g1n-glibc-2.32-35
/nix/store/g6441q8xrb8lq3lk5r4s7zjdv23bpxdx-attr-2.4.48
/nix/store/kzw4p3v89r2cbvbnm7g8kf9fh4z3c5m7-acl-2.2.53
/nix/store/xivj0vwm0pjpmwsjrc8qcca9fcfyxm4b-openssl-1.1.1i
/nix/store/jr56bx8a41h1x0wm7ih2mic5i3cjfcm1-coreutils-8.32
These look like they could be really helpful when actually writing derivations. I’d mainly image using them as debugging tools.
This is a great example. It is very simple and shows exactly what is going on. It makes sense that the .jar files are compressed, so the /nix/store/* paths inside them need to explicitly added in a nix-support file.
@danieldk Ah, I didn’t realize that this information is stored in the Nix DB.
I had assumed this information was computed at runtime when needed by commands like nix copy and nix-copy-closure.
However, given that there are special attributes like disallowedReferences that can be used from within Nix, I guess runtime dependencies are calculated after a derivation is built and preemptively stored in the Nix DB (as opposed to be computed lazily when needed).
I’m still interested in reading the actual Nix code that scans files and computes runtime dependencies if anyone knows where to find it in the Nix codebase.