nix-book/source/nix-language/derivations.adoc
Amy de Buitléir 0f5e7fb6bc temp
2025-10-12 21:48:22 +01:00

156 lines
4.6 KiB
Text

[#derivations]
= Derivations
Derivations can be created using the primitive built-in `derivation` function.
It takes the following arguments.
- `system` (e.g. `x86_64-linux`).
- `name`, the package name.
- `builder`, the executable that builds the package.
Attributes are passed to the builder as environment variables.
- `args` (optional), command line arguments to be passed to the builder.
- `outputs` (optional, defaults to `out`), output names.
Nix will pass them to the builder as environment variables containing
the output paths.
d = derivation { name = "myname"; builder = "mybuilder"; system = "mysystem"; }
[source]
.Example
....
nix-repl> d = derivation { name = "myname"; builder = "mybuilder"; system = "mysystem"; }
....
In place of using `derivation`, it is generally more convenient to use
`stdenv.mkDerivation`, which will be be introduced in
<<#mkDerivation>>
== Instantiation vs Realisation
When a derivation is _instantiated_ (_evaluated_),
the Nix expression is parsed and interpreted.
The result is a `.drv` file containing a derivation set.
The package is not built in this step.
// TODO Discuss nix-instantiate or the modern equivalent
The package itself is created when the derivation is _built_ (_realised_).
Any dependencies are also built at this time.
// TODO discuss nix-store -r or the modern equivalent
== Instantiate (evaluate) a derivation
Using the derivation "d" created above...
[source]
.Example
....
nix-repl> d
«derivation /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv»
....
That `.drv` file is plain text; it contains the derivation in a different format.
The mysterious sequence of characters in the filename is a hash of the derivation.
The hash is unique to this derivation.
We could have multiple derivations for a package, perhaps different versions or with different options enabled,
but each one would have a unique hash.
Any changes to the derivation would result in a new hash.
Using the hash, Nix can tell the different derivations apart,
and avoid rebuilding a derivation that has already been built.
We can inspect the derivation in the Nix repl.
[source]
.Example
....
nix-repl> d.drvAttrs
{ builder = "mybuilder"; name = "myname"; system = "mysystem"; }
....
We can examine the `.drv` file.
[source]
.Example
....
$ cat /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
Derive([("out","/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname","","")],[],[],"mysystem","mybuilder",[],[("builder","mybuilder"),("name","myname"),("out","/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"),("system","mysystem")])%
....
Or get a nicely formatted version.
[source]
.Example
....
$ nix show-derivation /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
{
"/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv": {
"outputs": {
"out": {
"path": "/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
}
},
"inputSrcs": [],
"inputDrvs": {},
"system": "mysystem",
"builder": "mybuilder",
"args": [],
"env": {
"builder": "mybuilder",
"name": "myname",
"out": "/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname",
"system": "mysystem"
}
}
}
....
== Find out where the package would be (or was) installed
Using the derivation "d" created above...
[source]
.Example
....
nix-repl> d.outPath
"/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
nix-repl> builtins.toString d # also works
"/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname"
....
== Build (realise) a derivation.
In the Nix REPL, using the derivation "d" created above...
[source]
.Example
....
nix-repl> :b d
error: a 'mysystem' with features {} is required to build '/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv', but I am a 'x86_64-linux' with features {benchmark, big-parallel, kvm, nixos-test}
....
Of course, this example failed to build because the builder and system are fake.
We can achieve the same result at the command line.
[source]
.Example
....
nix-build /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
this derivation will be built:
/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
error: a 'mysystem' with features {} is required to build '/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv', but I am a 'x86_64-linux' with features {benchmark, big-parallel, kvm, nixos-test}
....
== Remove a derivation
Delete a path from the store *if it is safe to do so* (i.e. if it is
eligible for garbage collection).
[source]
.Example
....
nix-store --delete /nix/store/rc3n0lc4aijyi9wwpmcss7hbxryz6bnh-foo
....
// TODO Contine from this point in ~/github/eolas/nix/nix.md