callPackage¶
Overview¶
callPackage is a nixpkgs helper (lib.customisation.callPackageWith), not a language builtin. It turns recipe functions shaped like { dep1, dep2, ... }: … into packages by filling each formal argument from a package set by name. The second attribute set supplies overrides or parameters the set cannot provide.
That convention is how nixpkgs stays a library of parameterised recipes rather than a pile of fully baked closures: one file per package, dependencies declared as function arguments, auto-wiring at the call site. Results get .override (via makeOverridable), so callers can re-invoke the same recipe with different arguments. Set-wide changes use overlays; see overlay vs override.
Details¶
Recipe as function¶
Prefer one file per package. Formal arguments name dependencies and helpers from the package set (stdenv, lib, other packages). The body typically builds with mkDerivation or a language-specific builder. See simple package.
callPackage accepts either a path (imported as the function) or an already-loaded function—same auto-fill either way.
Auto-fill¶
pkgs.callPackage ./pkg.nix { } introspects the recipe with lib.functionArgs, intersects those names with the package set (builtins.intersectAttrs), and applies auto // args. Attributes in the second set win: they override package-set values or supply non-package parameters (for example a string, or a chosen buildGoModule).
Arguments that have defaults in the recipe and are not present in the auto-fill set keep those defaults unless you pass them in the second set. Names that exist neither on the set nor as defaults must be supplied in args or evaluation fails.
.override¶
callPackage wraps the call in makeOverridable, so the result usually exposes .override: pkg.override { someDep = other; } re-runs the recipe with those substitutions merged over the original arguments. That is the usual single-package knob.
Do not confuse .override (recipe arguments) with .overrideAttrs (attributes passed to mkDerivation). Both may appear on the same derivation; see overlay vs override.
callPackageWith¶
lib.callPackageWith autoArgs returns a callPackage whose auto-fill source is autoArgs instead of the full pkgs. Interdependent local sets use that fixed-point style (laziness lets packages refer to itself before it is fully forced—see laziness and rec and fixed points):
callPackage = pkgs.lib.callPackageWith (pkgs // packages);
packages = { a = callPackage ./a.nix {}; /* … */ };
Manual inherit a; into every dependent call works for tiny graphs and becomes error-prone as the set grows; callPackageWith is the nixpkgs-scale answer.
There is also callPackagesWith / callPackages for a recipe that returns an attribute set of derivations: .override is attached to each leaf, not only the outer set.
Overlays¶
In final: prev: { ... }, call helpers on prev (prev.callPackage ./pkg { }) and take dependencies of new packages from final so they see the composed set. Details: overlays pattern. Prefer this over wide with pkgs; or ad-hoc import sprawl—see anti-patterns and import and fetch.
Examples¶
Bad → good: hand-wiring vs callPackage.
# avoid — every dependency named twice; easy to drift from the recipe
let
pkgs = import <nixpkgs> { };
helloFn = import ./hello.nix;
in
helloFn {
inherit (pkgs) writeShellScriptBin;
audience = "people";
}
# prefer — names filled from pkgs; second set is only for overrides / extras
pkgs.callPackage ./hello.nix { audience = "people"; }
Parameter + .override (from nix.dev):
# hello.nix
{
writeShellScriptBin,
audience ? "world",
}:
writeShellScriptBin "hello" ''
echo "Hello, ${audience}!"
''
# deps filled from pkgs; second set supplies parameters
pkgs.callPackage ./hello.nix { }
pkgs.callPackage ./hello.nix { audience = "people"; }
# same recipe, later tweak without re-calling callPackage
let
hello = pkgs.callPackage ./hello.nix { audience = "people"; };
in
hello.override { audience = "folks"; }
Custom set with callPackageWith:
let
callPackage = pkgs.lib.callPackageWith (pkgs // packages);
packages = {
a = callPackage ./a.nix { };
b = callPackage ./b.nix { }; # may depend on a by name
};
in
packages
See also¶
- Overlay vs Override
- Overlays Pattern
- Anti-Patterns
- Import and fetch
- mkDerivation
- Rec and Fixed Points
- simple-package.nix — callPackage-shaped wrapper fixture
- Example corpus