Skip to content

Make output paths/hashes indifferent to possible CA/FOD origin of sources #9259

@roberth

Description

@roberth

Is your feature request related to a problem? Please describe.

We can't currently swap out an inputSrcs derivation input for an inputDrvs input derivation input and get the same output path, despite no observable differences (with the possible exception of introspective features such as exportReferencesGraph, which we could force to be mutually exclusive with this improved hashing feature).

nix repl session illustrating how it currently works, and what this improvement entails

Currently we have some equivalence between FOD output paths and sources:

nix-repl> pkgs.emptyFile.outPath
"/nix/store/ij3gw72f4n5z4dz6nnzl1731p9kmjbwr-empty-file"

nix-repl> "${./empty-file}"
"/nix/store/ij3gw72f4n5z4dz6nnzl1731p9kmjbwr-empty-file"

However, as expected, the string contexts are different:

nix-repl> :p builtins.getContext pkgs.emptyFile.outPath
{ "/nix/store/jnghgcdkdc79p7qp4vfc27ryvnnm5igi-empty-file.drv" = { outputs = [ "out" ]; }; }

nix-repl> :p builtins.getContext "${./empty-file}"                       
{ "/nix/store/ij3gw72f4n5z4dz6nnzl1731p9kmjbwr-empty-file" = { path = true; }; }

In itself, this is not a problem. Fact is that they need to be built differently. One involves an FOD. The other was added to the store during instantiation.

That being the case, we can expect dependents to have different derivation hashes, representing the different build graph.

nix-repl> pkgs.concatText "derived" [ pkgs.emptyFile.outPath ]
«derivation /nix/store/nmzk7crah5himm4h3nbh6ry8331c99nq-derived.drv»

nix-repl> pkgs.concatText "derived" [ "${./empty-file}" ]      
«derivation /nix/store/6bs6pkf3z4gfmjk0ssr7qfldrvyr8qfy-derived.drv»

So far so good, but now we observe a difference in output paths, which is not necessary.

nix-repl> "${pkgs.concatText "derived" [ pkgs.emptyFile.outPath ]}"   
"/nix/store/4q9z73ak24fl3qr4j5wwkjbw0l7ch0rh-derived"

nix-repl> "${pkgs.concatText "derived" [ "${./empty-file}" ]}"      
"/nix/store/56phdxcpdv7d8zz4cj0a28iwz5akcpcz-derived"

By implementing this proposal (and enabling it in Nixpkgs), both output paths would have the value /nix/store/56phdxcpdv7d8zz4cj0a28iwz5akcpcz-derived.

Describe the solution you'd like

Instantiation works the same, except for the hashing of certain input-addressed outputs.

Specifically, when a derivation attribute flag such as __derivationAgnosticOutputHashing is enabled, inputs from FODs are ignored for the purpose of hashing; instead interpreting their output paths as inputSrcs.

Ignore __derivationAgnosticOutputHashing when the build could perceive the difference, e.g. when it has flags that would let it introspect its dependencies. I don't think it could use exportReferencesGraph on itself, so this may not even be a problem. I just haven't checked whether that was everything that needs to be controlled. TBD.

Describe alternatives you've considered

Fail instead of ignoring __derivationAgnosticOutputHashing. In practice this would mean that mkDerivation has to be clever about when to set the flag, which seems rather convoluted, pointless, and ever so slightly slower.

Additional context

Priorities

Add 👍 to issues you find important.

Metadata

Metadata

Assignees

No one assigned

    Labels

    derivation designIssues to consider for new versions of the derivation format (major or incremental)featureFeature request or proposalstoreIssues and pull requests concerning the Nix store

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions