mirror of
https://github.com/ryan4yin/nixos-and-flakes-book
synced 2024-12-20 09:23:13 +00:00
71 lines
No EOL
3.3 KiB
Markdown
71 lines
No EOL
3.3 KiB
Markdown
# `pkgs.callPackage`
|
|
|
|
In the previous section, we used the `import xxx.nix` syntax to import Nix files. This syntax simply returns the execution result of the file without any further processing.
|
|
|
|
Another method to import Nix files is `pkgs.callPackage`. Its syntax is `pkgs.callPackage xxx.nix { ... }`. However, unlike `import`, the Nix file imported by `pkgs.callPackage` must be a Derivation or a function that returns a Derivation. The result of `pkgs.callPackage` is also a Derivation, which represents a software package.
|
|
|
|
So, what does a Nix file that can be used as a parameter for `pkgs.callPackage` look like? You can refer to the `hello.nix`, `fcitx5-rime.nix`, `vscode/with-extensions.nix`, and `firefox/common.nix` files mentioned earlier. All of these files can be imported using `pkgs.callPackage`.
|
|
|
|
When the `xxx.nix` file used in `pkgs.callPackage xxx.nix {...}` is a function (most Nix packages follow this pattern), the execution flow is as follows:
|
|
|
|
1. `pkgs.callPackage xxx.nix {...}` first imports `xxx.nix` to obtain the function defined within it. This function usually has parameters like `lib`, `stdenv`, `fetchurl`, and sometimes additional custom parameters with default values.
|
|
|
|
2. Then, `pkgs.callPackage` searches for a value matching the parameter names from the current environment. Parameters like `lib`, `stdenv`, and `fetchurl` are defined in nixpkgs and will be found in this step.
|
|
|
|
3. Next, `pkgs.callPackage` merges its second parameter, `{...}`, with the attribute set obtained in the previous step. It then passes this merged set as the parameter to the function imported from `xxx.nix` for execution.
|
|
|
|
4. Finally, the result of the function execution is a Derivation.
|
|
|
|
The common use case for `pkgs.callPackage` is to import customized Nix packages and use them in Nix Modules.
|
|
|
|
For example, let's say we have a customized NixOS kernel configuration file named `kernel.nix`, which uses the SBC's name and kernel source as its variable parameters:
|
|
|
|
```nix
|
|
{
|
|
lib,
|
|
stdenv,
|
|
linuxManualConfig,
|
|
|
|
src,
|
|
boardName,
|
|
...
|
|
}:
|
|
(linuxManualConfig {
|
|
version = "5.10.113-thead-1520";
|
|
modDirVersion = "5.10.113";
|
|
|
|
inherit src lib stdenv;
|
|
|
|
# File path to the generated kernel config file (`.config` generated by make menuconfig)
|
|
#
|
|
# Here, we use a special usage to generate a file path from a string.
|
|
configfile = ./. + "${boardName}_config";
|
|
|
|
allowImportFromDerivation = true;
|
|
})
|
|
```
|
|
|
|
We can use `pkgs.callPackage ./kernel.nix {}` in any Nix Module to import and replace any of its parameters:
|
|
|
|
```nix
|
|
{ lib, pkgs, pkgsKernel, kernel-src, ... }:
|
|
|
|
{
|
|
# ......
|
|
|
|
boot = {
|
|
# ......
|
|
kernelPackages = pkgs.linuxPackagesFor (pkgs.callPackage ./pkgs/kernel {
|
|
src = kernel-src; # The kernel source is passed as a `specialArgs` and injected into this module.
|
|
boardName = "licheepi4a"; # The board name, used to generate the kernel config file path.
|
|
});
|
|
|
|
# ......
|
|
}
|
|
```
|
|
|
|
In the example above, we use `pkgs.callPackage` to pass different `src` and `boardName` parameters to the function defined in `kernel.nix`. This allows us to generate different kernel packages. By changing the parameters passed to `pkgs.callPackage`, `kernel.nix` can adapt to different kernel sources and development boards.
|
|
|
|
## References
|
|
|
|
- [Chapter 13. Callpackage Design Pattern - Nix Pills](https://nixos.org/guides/nix-pills/callpackage-design-pattern.html) |