我在理解Nix叠加层和覆盖模式时遇到了麻烦。我想做的是在gdb的“补丁”中添加一些内容,而无需复制/粘贴
整个推导。
从Nix Pills中,我可以看到重写只是模仿OOP,实际上,它只是集合的另一个属性。但是,那又如何工作呢?替代是从原始属性集到转换后的属性的一种功能,该功能又具有预定义的替代功能?
由于Nix是一种功能语言,因此您也没有变量,只有绑定(bind)可以在其他作用域中隐藏。但这仍不能解释叠加层如何实现其“魔力”。
通过〜/.config/nixpkgs,我已经配置了一个测试叠加层,大致像这样:
self: super:
{
test1 = super.gdb // { name = "test1"; buildInputs = [ super.curl ]; };
test2 = super.gdb // { name = "test2"; buildInputs = [ super.coreutils ]; };
test3 = super.gdb.override { pythonSupport = false; };
};
我得到:
nix-repl> "${test1}"
"/nix/store/ib55xzrp60fmbf5dcswxy6v8hjjl0s34-gdb-8.3"
nix-repl> "${test2}"
"/nix/store/ib55xzrp60fmbf5dcswxy6v8hjjl0s34-gdb-8.3"
nix-repl> "${test3}"
"/nix/store/vqlrphs3a2jfw69v8kwk60vhdsadv3k5-gdb-8.3"
但是之后
$ nix-env -iA nixpkgs.test1
replacing old 'test1'
installing 'test1'
你能解释一下这些结果吗?我是否正确,重写只能更改“定义的接口(interface)”,即函数的所有参数,并且由于“补丁”不是gdb的参数,因此我无法更改它?那么最好的选择是什么?
最佳答案
我会写一个答案,以防其他任何人迷路。
编辑21.8.2019:
我真正想要的是在https://nixos.org/nixpkgs/manual/#sec-overrides中描述的
覆盖派生和覆盖属性attrs
overlayDerivation基本上是“衍生(drv.drvAttrs//(f drv))”,overrideAttrs在https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/make-derivation.nix中定义为mkDerivation的一部分
然后我的代码如下所示:
gdb = super.gdb.overrideAttrs (oldAttrs: rec {
patches = oldAttrs.patches ++ [
(super.fetchpatch {
name = "...";
url = "...";
sha256 = "...";
})
];
});
问题标题具有误导性,源于我对派生的基本误解。叠加层的工作方式与广告宣传完全相同。而且它们可能也不是那么神奇。只是一些递归,其中endresult是上一步的结果////最后一个覆盖函数的输出。
What is the purpose of nix-instantiate? What is a store-derivation?
无论我哪里有错,请纠正我。
但是基本上,当您评估Nix代码时,“推导函数”会将描述性属性集(名称,系统,构建器)转换为“实际推导”。该“实际派生”还是一个属性集,但诀窍在于它由存储中的.drv文件支持。因此,从某种意义上讲,派生有副作用。 drv编码建筑物应该如何进行以及需要哪些依赖项。该文件的哈希值还确定了工件的目录名称(尽管尚未构建任何东西)。因此,nix存储中的名称也隐含地取决于所有构建输入。
当我基于将现有派生联系在一起而创建类似于Frankenstein的新派生类时,我所做的就是创建对同一个.drv文件的多个引用。好像我正在复制一个指针,结果是获得两个指向堆上相同值的指针。我可以更改一些元数据,但最终构建过程仍然相同。实际上,由于Nix是纯粹的,所以我敢说甚至没有办法写入文件系统(更改.drv文件)-除非再次使用一些包装了派生函数的东西。
另一方面,覆盖允许您创建“新实例”。由于具有“输入模式”,Nix中的每个包都是从依赖项属性集到最终调用“派生函数”的实际代码的函数。使用override,您可以再次调用该函数,这会使“派生函数”获得不同的参数。
关于Nix覆盖和覆盖图案,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57449098/