OFFSET偏移
← 文章目录OFFSET / FIELD NOTESNO. 024

Derivation:从表达式到构建产物

追踪求值、构建或替代下载以及 store 输出之间的关系。

所在专题Nix 语言与构建模型 ↗
约 3 分钟阅读开始阅读

Nix 表达式可以返回任意类型。只有求值到 derivation 及其依赖的构建描述,才进入这里讨论的构建流程。


什么是 Derivation?#

Derivation 是 Nix 的核心原语。它是一个后缀为 .drv 的文本文件,描述了如何构建一个软件包:

  1. 输入:源码、依赖包、构建脚本。
  2. 构建环境:构建平台、builder 和环境参数;沙盒隔离受平台及 Nix 设置控制,不能保证所有构建完全隔离。
  3. 输出:构建产生的二进制文件、库、文档。

构建过程解构#

  1. Evaluation (求值):Nix 解释器运行你的 .nix 代码,生成 .drv 文件。
  2. Realisation(实现产物):Nix 检查已有输出,优先使用可信缓存替代下载,否则按 .drv 执行构建;传统 nix-instantiate 对应求值生成构建描述,不等于运行构建。
  3. Storage (存储):构建结果被存入 /nix/store。

不可变、输入寻址与内容寻址#

  • 哈希前缀的由来:常见 derivation 输出采用输入寻址,由构建描述和依赖等决定路径;不能直接称为产物内容的哈希。固定输出和内容寻址 derivation 有不同路径规则,需区分。
  • 缓存魔法:如果你构建的东西哈希已经存在于二进制缓存(如 cache.nixos.org),Nix 就可以通过受信任的 substituter 下载相应输出,避免本地构建。

为什么你的配置也要进 /nix/store?#

当你运行 nixos-rebuild switch 时,模块求值会生成系统闭包的构建描述,输出包括激活脚本、服务定义、生成配置及其依赖;激活再把生成文件接到 /etc 等位置。源配置可能随 Flake 源进入 store,但回滚不等于恢复工作区源文件。

  • 这就是为什么你可以回滚系统:旧的配置文件也在 /nix/store 里,切换回来只是重新改一下软链接的指向。

开发者视角:nix-shell#

nix-shell 提供 derivation 的构建依赖与相应环境,通常不执行目标包的最终 builder,但仍可能构建/下载其依赖。nix develop 面向 Flake 开发环境,nix shell 则主要把包提供的程序加入 PATH;三者并不完全等价。


总结:Nix 三部曲#

  1. 描述:在 .nix 里写属性集。
  2. 推导:生成 .drv 方案。
  3. 产出:在 /nix/store 生成只读的目录。

参考与延伸

  1. NixOS 手册 ↗
  2. Nix 语言手册 ↗
  3. Nix:Derivations ↗
  4. Nix:Store Path ↗

根据技术笔记重新整理,示例使用通用名称。

沿专题继续阅读

Nix 语言与构建模型

  1. 01Nix 与 NixOS:存储、回滚和声明式思维
  2. 02Nix 语法:属性集、列表与内置函数
  3. 03Nix 函数与作用域
  4. 04Nix 属性集:递归与合并
  5. 05Derivation:从表达式到构建产物
CONTINUE READING / 下一篇Flake 结构:inputs 与 outputs

理解 Flake 输入、输出以及 self 和参数捕获的层级。