I have a fairly simple package which is defined (alongside many other packages) within a flake. If I run, say, nix build .#simple_package, then it builds fine, but (if from scratch) also takes a good long time to build python310 as well. As far as I can see, none of the inputs of this flake have a dependency on python, so I’m not quite sure where this dependency is coming from.
If I try nix why-depends .#simple_package github:nixos/nixpkgs#python310 then it tells me that python is not a dependency of simple_package.
However, if I do nix show-derivation --recursive .#simple_package, then I get a JSON which has its keys not just simple_package, but lots of other stuff as well (including a python dependency).
So I’m theorizing that
a) simple_package does indeed not have a python dependency, but
b) some other package within the flake does have a python dependency, and
c) nix show-derivation shows output for the whole flake, even if told to show output for only a single package within the flake, and (more speculatively)
d) my nix build .#simple_package command somehow requires that other packages in the flake be evaluated - though this doesn’t fit with my existing understanding of flakes, which is that the outputs are lazily evaluated.
If I anyone can cast some light on this then I’d be grateful.
This will check for a dependency between the flake’s simple_package and the build of python currently on nixpkgs master branch. There’s no reason to believe that’s the version of nixpkgs your flake is building simple_package against.
And just to be sure, by “aligning” you don’t mean that you’re simply using github:NixOS/nixpkgs/nixos-21.11#python310 on the command line, right? Because that also doesn’t necessarily refer to the same version of nixpkgs, if the channel has updated since your lock file was made.
Even aligning revs may not work since the python derivation may be overriden somehow. The most reliable way to find out would be to query the package until you can find the exact python output in question. Does nix path-info -r .#simple_package show the python output in the list?
That’s a useful command, I wasn’t aware of it at all. When I run this, it gives me two bits of output:
the paths of all the derivations in the flake, and
the paths of all the dependencies.
I do see python in the list of dependencies, which implies that something in that flake has python as a dependency, but it doesn’t unfortunately tell me which package(s) are the ones that need python.
It slightly surprises me that it’s showing everything, because I did ask for only .#simple_package (like in your example).
Because you said you were surprised that nix path-info -r .#simple_package is listing all the derivations in the flake. It doesn’t do that on its own; they must in fact be dependencies that you are not expecting.
As you already have been told, github:…#python310 might not be the same python as is seen by your derivation, often but not always, you can use --inputs-from to mitigate, though that only works if the derivations get used as they are and not altered by any of the known mechanisms like override or overrideAttrs
show-derivation tells you about build inputs, why-depends only considers runtime dependencies.
As path-info told you that there is a runtime dependency to python somehow, you can use exactly that path for why-depends.
Thank you, this is helpful. Using this approach, I’ve done some further investigation. On a fresh setup (within a docker container, specifically), I run nix path-info -r .#simple_package. This gives me output of the form:
these 3 derivations will be built:
these 86 paths will be fetched (157.19 MiB download, 650.25 MiB unpacked):
… with python appearing in the second list here, of paths to be fetched.
Both package1 and package2 are real dependencies of simple_package, so the derivations-to-be-built list here looks correct.
If I then investigate using why-depends, I can see that eg package1 is a dependency of simple_package, which makes sense:
$ nix why-depends /nix/store/y0ldhxvbj9rix2wwdbx9dgk5bgma8fn6-simple-package.drv /nix/store/7wpr947w9a5wsy6bfddw8vrg3vcw8qd6-python3-3.10.5-env
'/nix/store/y0ldhxvbj9rix2wwdbx9dgk5bgma8fn6-simple-package.drv' does not depend on '/nix/store/7wpr947w9a5wsy6bfddw8vrg3vcw8qd6-python3-3.10.5-env'
but neither is it a dependency of any of the other direct dependencies, eg
$ nix why-depends /nix/store/04g4dm5y481avrs3wb82cl1nwndha4id-package1.drv /nix/store/7wpr947w9a5wsy6bfddw8vrg3vcw8qd6-python3-3.10.5-env
'/nix/store/04g4dm5y481avrs3wb82cl1nwndha4id-package1.drv' does not depend on '/nix/store/7wpr947w9a5wsy6bfddw8vrg3vcw8qd6-python3-3.10.5-env'
So it is still unclear to me why python is being fetched here.
OK, this gets me straight to the answer. auto-patchelf-hook is a dependency that itself depends upon python. Which is a shame, because it’s slowing things down quite a lot, but it’s good to know how to diagnose this, so thank for your help.
You need to make sure that you have built the path first, or path-info will error out:
$ nix path-info -r nixpkgs#hello
this path will be fetched (0.04 MiB download, 0.17 MiB unpacked):
error: path '/nix/store/i9p5qqw7mbs9jhv871v3fzqw6s97npm5-hello-2.12' is not valid
After a build you get a more meaningful and appropriate information:
When built, I still do not see python among the list of paths for simple_package reveaeld by nix path-info (nor do I see auto-patchelf-hook), but I presume that this is because python is a build-time rather than run-time dependency. So far the only way to have nix acknowledge python as a dependency is by nix why-depends --derivation ... .