When trying to understand how pkgs/build-support/buildenv/default.nix works, I recently stepped over the article https://nixos.org/guides/nix-pills/06-our-first-derivation.html where I learned about the meaning of the attribute inputDrvs. So its for referring to other derivations for whatever reasons. It looks to me like it is the essential attribute that makes sure that when someone installs such a buildEnv-derivation, that the referenced derivations are present in the Nix-store as well.
I wanted to double-check this in the documentation. Although I assume it to play a quite important role, in the manual it is not directly mentioned as an attribute in the section about derivations. Instead it says Every other attribute is passed as an environment variable to the builder. Is this really correct? This documentation does not say anything about how json-values are treated. So I expected it to be treated as a string and checked via nix develop <my-buildEnv-derivation>, if it was present in the environment of the dev-shell. It wasn’t. So what is actually happening here? Is a json treated recursively so that the derivations in inputDrvs are found and evaluated? Or is it different?
Yes, it is. And unfortunately, nixpkgs builders usually inherit that behavior, though you can usually use env.ENVVAR = ...; to be explicit about it. They’re mostly passed as strings, unless you use __structuredAttrs = true; in which case they are passed as proper types.
Yes, inputDrvs are essential for forming dependency graphs. They are computed automatically using one of the unique but largely invisible features of the Nix language: string contexts.
Nixpkgs build helpers (functions that provide simpler interfaces for common use cases when building software) use that ability under the hood. If you want certain other derivations to be dependencies, one way is to add a file to the build output that contains strings with contexts that refer to those other derivations.
If you still have questions, I recommend reading the source code. (documention is bad, let’s read the source code)
The entire code to build a derivation.
it’s a bit long (1.5k lines), so I will give you the part you needed.
Note that you can see coerceToString in the code. It may change the local variable context, which holds the ‘string contexts’ and is used later. drv.env is used to set env for the builder.
‘string contexts’ become inputDrvs and inputSrcs. inputDrvs is NOT set by the user.
Do you mean an attrset? An attrset is not allowed to be coerced unless it has the __toString or outPath attribute.
No, it wouldn’t replace that[1]. The former page (§10.1.2) is about the internal representation, i.e. what the manual calls a “store derivation”, while the latter page (§5.4.1) is about the derivation builtin function used to write a “derivation”, which is what the user might interact with (if they’re masochistic enough to not use the nixpkgs build helpers, anyway).
(And yes, this terminology is insanely confusing.)
Well, I’m not on the docs team, so grain of salt here. ↩︎
What I wonder, when having a look at inputDrvs is, that there is no distinction between input-derivations that are needed to be in the store when one wants to execute a program in the output of the target-derivation and those which are needed just to build the target-derivation (without executing anything). That probably means when one copies a derivation from a substituter, Nix makes sure that even e.g. compilers needed for building it are in the Nix store.
For future reference: What I mean is that inputDrvs is not mentioned as input-attribute of a derivation. The answer from @waffle8946 explains that. It is only part of the internal representation which diverges from the signature of the derivation-function in the Nix-DSL. I was not aware of this and wondered if it is passed into the builder as a string. But it is not passed, as @waffle8946’s explanation shows.
I wonder if it is a good idea to introduce there close to the head-line an info-box on how it differs from
It does link the protocols pages. It doesn’t refer to the Nix language because nothing in the store layer cares about the Nix language — this layering is introduced earlier in the manual when going over the architecture, not not restated for each store layer concept.
Rather, the documentation for buildins.derivation is now getting smaller, because relative information is moved to the store layer, and it links that instead. So in the other direction (because the language is definitely aware of the store layer, unlike the store layer not caring about the language) the difference and reliance should be very clear.