3.3 KiB
pkgs.callPackage
In the previous content, We have used import xxx.nix
to import Nix files many times, this syntax simply returns the execution result of the file, without any further processing of it.
pkgs.callPackage
is also used to import Nix files, its syntax is pkgs.callPackage xxx.nix { ... }
, but unlike import
, the Nix file imported by it must be a Derivation or a function that returns a Derivation. Its result is a Derivation(a software package) too.
So what does the Nix file that can be used as a parameter of pkgs.callPackge
look like? You can take a look at the hello.nix
fcitx5-rime.nix
vscode/with-extensions.nix
firefox/common.nix
we mentioned earlier, they can all be imported by pkgs.callPackage
.
When the xxx.nix
used in pkgs.callPackge xxx.nix {...}
is a function (most Nix packages are like this), the execution flow is as follows:
pkgs.callPackge xxx.nix {...}
will firstimport xxx.nix
to get the function defined in it. The parameters of this function usually havelib
,stdenv
,fetchurl
and other parameters, as well as some custom parameters, which usually have default values.- Then
pkgs.callPackge
will first look up the value matching the name from the current environment as the parameter to be passed to the function. parameters likelib
stdenv
fetchurl
are defined in nixpkgs, and they will be found in this step. - Then
pkgs.callPackge
will merge its second parameter{...}
with the attribute set obtained in the previous step, and then pass it to the function imported fromxxx.nix
and execute it. - Finally we get a Derivation as the result of the function execution.
The common usage of pkgs.callPackage
is to import customized Nix packages and used them in Nix Module.
For example, we have customized a NixOS kernel configuration kernel.nix
, and used the SBC's name and kernel source as its variable parameters:
{
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(the `.config` generated by make menuconfig)
#
# here is a special usage to generate a file path from a string
configfile = ./. + "${boardName}_config";
allowImportFromDerivation = true;
})
Then we can use pkgs.callPackage ./kernel.nix {}
in any Nix Module to import and use it, and replace any of its parameters:
{ lib, pkgs, pkgsKernel, kernel-src, ... }:
{
# ......
boot = {
# ......
kernelPackages = pkgs.linuxPackagesFor (pkgs.callPackage ./pkgs/kernel {
src = kernel-src; # 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.
});
# ......
}
Just like the example above, we can use pkgs.callPackage
to pass different src
and boardName
to the function defined in kernel.nix
through pkgs.callPackage
, so that different kernel packages can be generated.
The kernel.nix
can be used to adapt to different kernel sources and different development boards by changing the parameters passed to it.