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

问题描述

在Eelco Dolstra论文的第5.4节第108页中,定义了hashDrv函数,其中在框69上,inputDrvshashDrv替换(递归)。文件的解析内容。我不理解执行此替换的动机,而不是仅使用inputDrvs文件名本身而不执行替换。

此替换的结果似乎是商店派生的输出值从所有输出值的计算中递归地删除。但是,由于输出值本身是根据进入hashDrv的所有其他数据计算得出的,因此执行此替换操作似乎没有任何积极的结果。

实际上,似乎存在负面影响,因为这种替换意味着无法从派生内容本身来计算输出哈希文件,相反,您需要具有整个输入派生树来执行计算(请参阅{{3 }}。

尽管当然需要将派生本身的输出哈希值从其hashDrv的计算中排除,但如果仅从其他内容中简单地导出输出哈希值,似乎会更好派生文件

解决方法

好吧,首先,最好还是放下inputDrvs并仅使用这些输入的输出路径来创建存储路径,请参见https://github.com/nixos/nix/commit/1511aa9f488ba0762c2da0bf8ab61b5fde47305d的提交消息,以供Eelco说尽可能

请注意,这是一项特权操作,因为您可以构造一个 建立任何存储路径的派生。解决这个问题 需要更改哈希方案(即,输出路径应为 从BasicDerivation中的其他字段计算得出,允许它们 已验证,无需访问其他衍生产品)。但是,这将是 非常好,因为它将允许无.drv的构建(例如“ nix-env -i”就不必将任何.drv文件写入磁盘。

但是,给定的hashDrv优于仅按原样哈希drv的那个,因为“模固定输出派生部分”。通过忽略其余的固定输出派生,而仅返回基于固定输出哈希(和名称)的哈希,我们可以更改固定输出派生产生数据的方式,而无需更改下游哈希。在今天的Nixpkgs中,例如,我们可以这样做https://github.com/NixOS/nixpkgs/pull/82130,而这不会是大规模的重建。