A derivation is an instruction that Nix uses to realise a Nix package.
They're created using a special derivation
function in the Nix language.
They can depend on any number of other derivations and produce one or more final outputs.
A derivation and all of the dependencies required to build it—direct dependencies, and all dependencies of those dependencies, etc—is called a closure.
The most common outputs:
out
, the most generic onelib
, for library outputsdev
, general development resources such as header filesman
, for manual pagesA derivation and all of the dependencies required to build it—direct dependencies, and all dependencies of those dependencies, etc—is called a package closure.
You may find it helpful to think of a derivation as the plan or blueprint for a Nix package.
In the Nix language, derivations are created using the derivation
function.
Here's the type signature for derivation
expressed as a Haskell-ish signature:1
derivation ::
{ system : String
, name : String
, builder : Path | Derivation
, ?args : [String]
, ?outputs : [String]
} -> Derivation
Here's an example derivation:
derivation {
# A name for the derivation (whatever you choose)
name = "hello-text";
# The system realising the derivation
system = "x86_64-linux";
# The program realising the derivation
builder = "bash";
# Arguments passed to the builder program
args = ["-c" "mkdir $out && echo Hello world > $out/hello.txt"]
};
And that's it!
The derivation
function takes only these arguments.
But derivations can be far less straightforward, because the scripting logic that you pass via args
can be arbitrarily complex.
If Nix sees this string...
buildPhase = ''
mv ${pkgs.website}/favicon.ico
'';
The string output of a derivation is always a Nix store path
There are two special variables to be aware of when writing derivations:
$out
represents the root of the directory structure for build output.$src
represents the build sources.Most derivations in the Nix ecosystem are based on the mkDerivation
function from the standard environment.
While you can create derivations using the raw derivation
function, it's far more common to use a wrapper function around it.
Perhaps the most commonly used wrapper function is stdenv.mkDerivation
.
Arguments:
name
of the package. If you specify pname
and version
instead, the name
ends up ${pname}-${version}
.Outside of stdenv.mkDerivation
, there are many custom derivation wrappers for specific languages, frameworks, and more (and many of those actually wrap stdenv.mkDerivation
).
Some examples:
buildGoModule
for GobuildRustPackage
for RustbuildPythonApplication
for PythonYou're likely to encounter many more in the Nix ecosystem.
And you're always free to create your own derivation functions and even wrap helper functions like buildPythonApplication
.