何时以及如何使用 default.nix、shell.nix 和 release.nix?

When and how should default.nix, shell.nix and release.nix be used?

学习如何使用 Nix 包管理器时遇到的第一种 Nix 表达式是 default.nix;在精彩的 NixOS IRC 频道上,我了解到 shell.nixrelease.nix 的存在。

我的印象是 - 大致 -default.nixnix-build 一起用于简单地构建包,shell.nixnix-shell 一起用于创建一个与包的交互环境,release.nix 在部署包时与 nixops 一起使用。

由于这可能不完整且部分不正确,而且似乎没有明确记录,因此我希望对这类 "standard files" 进行清晰准确的解释;特别是,对于这些文件类型中的每一个(以及我遗漏的任何其他标准文件),我想知道:

  1. 此类文件的典型用例是什么?它们有什么用?
  2. 这种文件类型的结构通常是怎样的?它的最低要求是什么?
  3. 您能否在其使用上下文 中展示此类文件的范例示例 ,即带有使用说明并包括在 shell 中使用它所需的代码行还是另一个 Nix 表达式?

作为额外的奖励问题,我想知道在将软件包安装到 NixOS 模块时应该使用这些标准文件中的哪些(如果有的话)?那要怎么做呢?

首先,default.nixshell.nix在Nix工具中有特殊含义,但release.nix是一个方便的

接下来运行nix-build时使用default.nix作为默认文件,运行[=]时使用shell.nix作为默认文件16=]。就像你说的。

接下来,default.nix 不仅仅用于 nix-build。例如,<nixpkgs/lib/default.nix> 用作函数的聚合器,并且不包含派生。所以并不是每个 default.nix 都应该是 "built"(但如果 default.nix 是派生的属性集,它将是可构建的,并且 nix-build 将构建所有这些)。

接下来,nix-shell如果没有找到shell.nix将使用default.nix

接下来导入目录时使用default.nix作为默认文件。所以如果你写 x = import ./some/directory;,那么 ./some/directory/default.nix 将被导入。这实际上应该可以解释为什么 "nix-build ." 使用 default.nix.

最后,default.nix中的推导有两种常见格式:推导和callPackage推导。你不能 nix-build 后者。几乎所有 nixpkgs 中的包都是用这种风格编写的,参见 hello。但是你可以 nix-build -E 'with import <nixpkgs> { }; callPackage ./path/to/default.nix { }' 作为解决方法。 nix-shell 也支持这个 -E 论点。

正如@danbst 所说,只有 default.nixshell.nix 对 nix 工具有特殊含义,除此之外没有真正的标准,每个人都可以自由使用最适合他们需要的东西。

也就是说,这并不意味着你不能设置自己的一套规则,个人对于单个推导项目我喜欢按以下方式排列nix文件:

  • default.nix: 使用callpackage导入derivation.nix.
  • derivation.nix: nixpkgs风格推导文件。
  • shell.nix: nix-shell 文件。
  • module.nix:NixOS模块文件,导入default.nix.
  • test.nix: NixOS 测试文件。
  • release.nix: Hydra 作业集声明。

我们在东京 NixOS 聚会上讨论了这个话题,可以找到这样的代码组织示例 here