nix-env:了解活动 Nix 表达式中的可用属性路径

nix-env: understading available attribute paths in the active Nix expression

在我的 NixOS 机器上,我可以使用 nix-env 以两种方式查询 ghc 包:

一个是 nix-env -f '<nixpkgs>' -qaP ghc,它导致输出

ghc  ghc-8.6.5

另一个是 nix-env -qaP ghc,它导致输出

nixpkgs.ghc  ghc-8.6.5

对于第二种情况,我想理解为什么活跃的Nix表达式有一个nixpkgs根属性。

~/.nix-defexpr文件夹和几个子文件夹的内容如下:

如何从~/.nix-defexpr的内容中组装出活跃的Nix表达式?为什么没有 channels 根属性? nixpkgs 根属性的名称是源自 nixpkgs 文件夹的名称,还是源自文件夹的内容,或许源自 default.nix 文件中声明的内容?

Nix manual 有一些关于如何组装 .nix-defexpr 的信息:

The Nix expressions in this directory are combined into a single set, with each file as an attribute that has the name of the file.

不过,它没有提到如果内容本身就是目录会发生什么。但我发现 this GitHub issue 更能解释事情:

  • If a directory is a valid expression (i.e. has default.nix) its expression will be added to the set, otherwise it will be traversed recursively.
  • Names of intermediate directories are completely ignored (i.e. do not take any part in attrpaths).
  • manifest.nix is recursively ignored.

因此,没有 channels 根属性,因为该文件夹没有 default.nix 表达式。

好的。然后,作为实验,我创建了一个文件夹 .nix-defexpr/foo,其中包含一个文件 default.nix,其中包含内容 { zzz = 4; }。当我执行 nix-env --install -A foo.zzz 我得到:

error: expression does not evaluate to a derivation (or a set or list of those)

也就是说它真的找到了路径!问题是 4 不是推导。

但是,如果我创建另一个文件夹 .nix-defexpr/whatever 并将文件夹 foo 的副本放在那里怎么办?不会有某种名称冲突吗?是的,有:

8f792ff4f96a:~# nix-env --install -A foo.zzz
warning: name collision in input Nix expressions, skipping '/root/.nix-defexpr/whatever/foo'