nixos-and-flakes-book/docs/zh/nixpkgs/callpackage.md
2023-06-23 22:19:10 +08:00

2.1 KiB
Raw Blame History

前面我们介绍并大量使用了 import xxx.nix 来导入 Nix 文件,这种语法只是单纯地返回该文件的执行结果,不会对该结果进行进一步处理。 比如说 xxx.nix 的内容是形如 {...}: {...},那么 import xxx.nix 的结果就是该文件中定义的这个函数。

pkgs.callPackage 也是用来导入 Nix 文件的,它的语法是 pkgs.callPackage xxx.nix { ... }. 但跟 import 不同的是,它导入的 nix 文件内容必须是一个 Derivation 或者返回 Derivation 的函数,它的执行结果一定是一个 Derivation也就是一个软件包。

那可以作为 pkgs.callPackge 参数的 nix 文件具体长啥样呢,可以去看看我们前面举例过的 hello.nix fcitx5-rime.nix vscode/with-extensions.nix firefox/common.nix,它们都可以被 pkgs.callPackage 导入。

pkgs.callPackge xxx.nix {...} 中的 xxx.nix,其内容为一个函数时(绝大多数 nix 包都是如此),执行流程如下:

  1. pkgs.callPackge xxx.nix {...} 会先 import xxx.nix,得到其中定义的函数,该函数的参数通常会有 lib, stdenv, fetchurl 等参数,以及一些自定义参数,自定义参数通常都有默认值。
  2. 接着 pkgs.callPackge 会首先从当前环境中查找名称匹配的值,作为将要传递给前述函数的参数。像 lib stdenv fetchurl 这些都是 nixpkgs 中的函数,在这一步就会查找到它们。
  3. 接着 pkgs.callPackge 会将其第二个参数 {...} 与前一步得到的参数集attribute set进行合并得到一个新的参数列表然后将其传递给该函数并执行。
  4. 函数执行结果是一个 Derivation也就是一个软件包。

这个函数比较常见的用途是用来导入一些自定义的 Nix 包,比如说我们自己写了一个 hello.nix,然后就可以在任意 Nix Module 中使用 pkgs.callPackage ./hello.nix {} 来导入并使用它。

参考