在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
文件中声明的内容衍生的? / p>
答案 0 :(得分:2)
Nix manual提供了有关.nix-defexpr
组装方式的一些信息:
此目录中的Nix表达式被合并为一个集合, 并将每个文件作为具有文件名的属性。
尽管内容本身是目录,但没有提到会发生什么。但是我发现this GitHub issue可以解释更多内容:
- 如果目录是有效的表达式(即具有default.nix),则该表达式将被添加到集合中,否则将被遍历 递归地。
- 中间目录的名称被完全忽略(即,不参与attrpaths)。
- manifest.nix被递归忽略。
因此,由于文件夹没有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'