gpt4 book ai didi

Nix 覆盖和覆盖模式

转载 作者:行者123 更新时间:2023-12-01 00:11:59 26 4
gpt4 key购买 nike

我无法理解 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 中描述了我真正想要的

覆盖推导 覆盖属性

overrideDerivation 基本上是“derivation (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 存储中的名称也隐含地取决于所有构建输入。

当我基于将现有的派生绑定(bind)在一起创建一种类似于科学怪人的新派生时,我所做的只是创建对同一个 .drv 文件的多个引用。好像我正在复制一个指针,结果是让两个指针指向堆上的相同值。我能够更改一些元数据,但最终构建过程仍然相同。事实上,由于 Nix 是纯粹的,我敢打赌,甚至没有办法写入文件系统(更改 .drv 文件)——除非再次使用包装派生函数的东西。

另一方面,覆盖允许您创建“新实例”。由于“输入模式”,Nix 中的每个包都是从依赖属性设置到最终调用“派生函数”的实际代码的函数。通过覆盖,您可以再次调用该函数,这使得“派生函数”获得不同的参数。

关于Nix 覆盖和覆盖模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57449098/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com