Nix 表达式可以返回任意类型。只有求值到 derivation 及其依赖的构建描述,才进入这里讨论的构建流程。
什么是 Derivation?#
Derivation 是 Nix 的核心原语。它是一个后缀为 .drv 的文本文件,描述了如何构建一个软件包:
- 输入:源码、依赖包、构建脚本。
- 构建环境:构建平台、builder 和环境参数;沙盒隔离受平台及 Nix 设置控制,不能保证所有构建完全隔离。
- 输出:构建产生的二进制文件、库、文档。
构建过程解构#
- Evaluation (求值):Nix 解释器运行你的
.nix代码,生成.drv文件。 - Realisation(实现产物):Nix 检查已有输出,优先使用可信缓存替代下载,否则按
.drv执行构建;传统nix-instantiate对应求值生成构建描述,不等于运行构建。 - 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 三部曲#
- 描述:在
.nix里写属性集。 - 推导:生成
.drv方案。 - 产出:在
/nix/store生成只读的目录。
参考与延伸
根据技术笔记重新整理,示例使用通用名称。