Skip to content

Instantly share code, notes, and snippets.

@rrbutani
Last active January 20, 2022 21:01
Show Gist options
  • Save rrbutani/bf1782dec1307f9e7f3520946202877d to your computer and use it in GitHub Desktop.
Save rrbutani/bf1782dec1307f9e7f3520946202877d to your computer and use it in GitHub Desktop.
`nix-env` special output bug

nix-env -iA nixpkgs.netcat doesn't seem to install the nc output

netcat is just set to libressl.nc they are indeed the same derivation; these print out the same thing:

  • nix eval "(import <nixpkgs> {}).libressl.drvPath"
  • nix eval "(import <nixpkgs> {}).netcat.drvPath"

outputName is, however, different, as expected

the peculiar bit is that nix build (i.e. nix build '<nixpkgs>' -A netcat) will build and emit the nc output


nix-env grabs the outputs to install from .meta.outputsToInstall

  • if this is not specified explicitly (as it isn't for libressl), it's specified by mkDerivation
    • ^ yields the first of bin/out that are present in outputs or the first thing in outputs if neither are present
    • plus man if it's in outputs
  • lib.extendDerivation (called in mkDerivation here) is what sets us the attrs in the derivation for each output
    • it sets outputSpecified and outputName but otherwise more or less has the output attributes be identical to their parent derivation
    • note that it also creates all (a list of the output derivations)

nix build is supposed to (when given a derivation and not a list of derivations) build the "first output" and indeed poking at the source code seems to confirm that it does so by looking at the outputName

(I can't tell where the outputName for the top-level derivation actually gets set. (it's set to the first thing in outputs). I think this is the bit that does it (i.e. take the first derivtaion in the list) but I haven't traced through how that's actually called in primops.cc)

deps (or at least build deps?) seem to back off and use the whole derivation when outputSpecified is true (if I'm reading this right)


All this is to say I'm pretty sure this is all behavior that is consistent with the source code and isn't specific to my system or some form of user error.

Even so, this does seem suboptimal; I certainly expected nix-env -iA nixpkgs.netcat to actually surface the netcat binary in my profile which I don't think is unreasonable.

Not sure what (if anything) the right fix is here; should extendDerivation modify meta.outputsToInstall? should nix-env use outputName instead of (or in addition to?) meta.outputsToInstall when outputSpecified is true?

If either of the above seem like a reasonable change to make, I'm very happy to try to make a PR.


not sure how this wasn't found before; I guess not many people use nix-env to actually install things? also to be fair not that many packages in nixpkgs actually just map to an output of another derivation, I guess ^ [a-z]*[ ]*=[ ]*[a-z]*\.[a-z-]*; is a crude heuristic but is yields under a 100 entries in top-level/all-packages.nix, not all of which actually point to an output from another derivation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment