在 Nix 中,为什么 hashDrv 用其内容的递归 hashDrv 替换 inputDrvs

In Nix, why does hashDrv replace the inputDrvs with a recursive hashDrv of their contents

在 Eelco Dolstra 论文第 108 页的第 5.4 节中,有一个 hashDrv 函数的定义,其中,在方框 69 中,inputDrvs 被(递归地)替换为 hashDrv 解析后的文件内容。我不明白执行此替换的动机,而不是仅使用 inputDrvs 文件名本身而不执行替换。

这种替换的结果似乎是存储推导的输出值被递归地从所有输出值的计算中移除。但是,由于输出值本身是根据进入 hashDrv 的所有其他数据计算得出的,因此执行此替换操作似乎没有任何积极影响。

确实,这似乎会产生负面影响,因为这种替换意味着无法根据推导内容本身计算输出哈希文件,相反,您需要使用整个输入推导树来执行计算(请参阅 https://github.com/NixOS/nix/issues/2789#issuecomment-595143352).

虽然推导本身的输出哈希值当然需要从其 hashDrv 的计算中排除,但如果输出哈希值只是简单地从导出文件的其他内容。

好的,首先,最好还是删除 inputDrvs 并只使用这些输入的输出路径来创建存储路径,请参阅 https://github.com/nixos/nix/commit/1511aa9f488ba0762c2da0bf8ab61b5fde47305d 的提交消息Eelco 说了这么多:

Note that this is a privileged operation, because you can construct a derivation that builds any store path whatsoever. Fixing this will require changing the hashing scheme (i.e., the output paths should be computed from the other fields in BasicDerivation, allowing them to be verified without access to other derivations). However, this would be quite nice because it would allow .drv-free building (e.g. "nix-env -i" wouldn't have to write any .drv files to disk).

但是,给出的 hashDrv 比仅散列 drv as-is 的要好,因为“模数固定输出推导部分”。通过忽略其余固定输出派生并仅返回基于固定输出散列(和名称)的散列,我们获得了更改固定输出派生如何生成数据的能力,而无需更改下游散列。这就是今天在 Nixpkgs 中的方式,例如,我们可以做 https://github.com/NixOS/nixpkgs/pull/82130 而不会是大规模重建。