A derivation is an attribute set that describes a build
environment. Derivations on-disk are stored in .drv
files.
nix-repl> derivation { name = "my_derivation"; builder = "my_builder"; system = "my_system"; }
«derivation /nix/store/3k6kqw1s85kaz5vgm43v6mqxjpn812sy-my_derivation.drv»
❤ (theia) ~> nix show-derivation /nix/store/d4ncq4ww3zmmm6j6q0j17631qbid59m3-my_name.drv
{
"/nix/store/d4ncq4ww3zmmm6j6q0j17631qbid59m3-my_name.drv": {
"outputs": {
"out": {
"path": "/nix/store/70ppafkb5a37k6im23cwgrnpl243v1mq-my_name"
}
},
"inputSrcs": [],
"inputDrvs": {},
"system": "my_system",
"builder": "my_builder",
"args": [],
"env": {
"builder": "my_builder",
"name": "my_name",
"out": "/nix/store/70ppafkb5a37k6im23cwgrnpl243v1mq-my_name",
"system": "my_system"
}
}
}
… or not …
❤ (theia) ~> nix-build /nix/store/d4ncq4ww3zmmm6j6q0j17631qbid59m3-my_name.drv
this derivation will be built: /nix/store/d4ncq4ww3zmmm6j6q0j17631qbid59m3-my_name.drv
error: a 'my_system' with features {} is required to build
'/nix/store/d4ncq4ww3zmmm6j6q0j17631qbid59m3-my_name.drv',
but I am a 'x86_64-linux' with features {benchmark, big-parallel, kvm, nixos-test}
- Specifies the name and version of the package being built
- Format:
${pname}-${version}
- Somewhat deprecated/ out of style
- Use
pname
andversion
explicitly instead!
- Use
- Builders are the root process which produces a package output.
- Usually this is
${pkgs.bash}/bin/bash
- It is very unusual to change the builder
- The current build system
- This value can be changed for cross-compilation
- By default filled in with
builtins.currentSystem
- More on this during the cross-compilation day
In fact, you can create a useless derivation very easily!
nix-repl> { type = "derivation"; }
«derivation ???»
- Very basic derivation builder function:
derivation
- Much more useful derivation builder function:
mkDerivation
nix-repl> hello
«derivation /nix/store/b3rw75kc63qd9ssb4khbf47lcj1g6ay7-hello-2.12.1.drv»
The raw .drv
file on-disk.
Derive(
[("out","/nix/store/3ng68pn55h3na7dayydpqrh4bm1ag2sl-hello-2.12.1","","")],
[("/nix/store/1df310z72algpp1nxg45rhq2dfvkbrp5-bash-5.1-p16.drv",["out"]),
("/nix/store/dyivpmlaq2km6c11i0s6bi6mbsx0ylqf-hello-2.12.1.tar.gz.drv",["out"]),
("/nix/store/mjzy4drz2z4sbj3h5m7h3ndyvaqzdl80-stdenv-linux.drv",["out"])],
["/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"],
"x86_64-linux",
"/nix/store/lj2bdg618093ny9505d0nzzjdq0fwp8a-bash-5.1-p16/bin/bash",
["-e","/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"],
[("buildInputs",""),("builder","/nix/store/lj2bdg618093ny9505d0nzzjdq0fwp8a-bash-5.1-p16/bin/bash"),
("cmakeFlags",""),("configureFlags",""),("depsBuildBuild",""),
("depsBuildBuildPropagated",""),("depsBuildTarget",""),("depsBuildTargetPropagated",""),
("depsHostHost",""),("depsHostHostPropagated",""),("depsTargetTarget",""),("depsTargetTargetPropagated",""),
("doCheck","1"),("doInstallCheck",""),("mesonFlags",""),("name","hello-2.12.1"),("nativeBuildInputs",""),
("out","/nix/store/3ng68pn55h3na7dayydpqrh4bm1ag2sl-hello-2.12.1"),("outputs","out"),("patches",""),
("pname","hello"),("propagatedBuildInputs",""),("propagatedNativeBuildInputs",""),
("src","/nix/store/pa10z4ngm0g83kx9mssrqzz30s84vq7k-hello-2.12.1.tar.gz"),
("stdenv","/nix/store/43215b010yhnvpmr169abg324zq1l0sr-stdenv-linux"),
("strictDeps",""),("system","x86_64-linux"),("version","2.12.1")]
)
The evaluated .drv
file.
{
"/nix/store/qcvlk255x98i46cg9vphkdw5pghrizsh-hello-2.12.1.drv": {
"outputs": {
"out": {
"path": "/nix/store/g2m8kfw7kpgpph05v2fxcx4d5an09hl3-hello-2.12.1"
}
},
"inputSrcs": [
"/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"
],
"inputDrvs": {
"/nix/store/2knhp55njxnhh7j1l0w7ns0hi6bxmn1k-stdenv-linux.drv": [
"out"
],
"/nix/store/3sjd4vvbdssljiy45a9igjy9kkxd2skq-bash-5.1-p16.drv": [
"out"
],
"/nix/store/42j03b6x0cdj84b77mhkh9zwqgq61w6d-hello-2.12.1.tar.gz.drv": [
"out"
]
},
"system": "x86_64-linux",
"builder": "/nix/store/dsd5gz46hdbdk2rfdimqddhq6m8m8fqs-bash-5.1-p16/bin/bash",
"args": [
"-e",
"/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"
],
"env": {
"buildInputs": "",
"builder": "/nix/store/dsd5gz46hdbdk2rfdimqddhq6m8m8fqs-bash-5.1-p16/bin/bash",
"cmakeFlags": "",
"configureFlags": "",
"depsBuildBuild": "",
"depsBuildBuildPropagated": "",
"depsBuildTarget": "",
"depsBuildTargetPropagated": "",
"depsHostHost": "",
"depsHostHostPropagated": "",
"depsTargetTarget": "",
"depsTargetTargetPropagated": "",
"doCheck": "1",
"doInstallCheck": "",
"mesonFlags": "",
"name": "hello-2.12.1",
"nativeBuildInputs": "",
"out": "/nix/store/g2m8kfw7kpgpph05v2fxcx4d5an09hl3-hello-2.12.1",
"outputs": "out",
"patches": "",
"pname": "hello",
"propagatedBuildInputs": "",
"propagatedNativeBuildInputs": "",
"src": "/nix/store/pa10z4ngm0g83kx9mssrqzz30s84vq7k-hello-2.12.1.tar.gz",
"stdenv": "/nix/store/kmfaajdpyyyg319vfqni5jm9wkxjmf73-stdenv-linux",
"strictDeps": "",
"system": "x86_64-linux",
"version": "2.12.1"
}
}
}
- Part 0: evaluate package definition, compute hashes, and create
.drv
file - Part 1: evaluate derivation output
- Part 2: build package according to derivation
❤ (theia) ~> nix-build /nix/store/qcvlk255x98i46cg9vphkdw5pghrizsh-hello-2.12.1.drv
this path will be fetched (0.05 MiB download, 0.22 MiB unpacked):
/nix/store/g2m8kfw7kpgpph05v2fxcx4d5an09hl3-hello-2.12.1
copying path '/nix/store/g2m8kfw7kpgpph05v2fxcx4d5an09hl3-hello-2.12.1' from 'https://cache.nixos.org'...
/nix/store/g2m8kfw7kpgpph05v2fxcx4d5an09hl3-hello-2.12.1
Don’t build derivations by hand!
Instead use the mkDerivation
function instead.
Have a look at (some of) the arguments this function takes.
{
# ...
, nativeBuildInputs ? [] # -1 -> 0 N.B. Legacy name
, buildInputs ? [] # 0 -> 1 N.B. Legacy name
, checkInputs ? []
, installCheckInputs ? []
, configureFlags ? []
, cmakeFlags ? []
, mesonFlags ? []
, doCheck ? config.doCheckByDefault or false
, doInstallCheck ? config.doCheckByDefault or false
, strictDeps ? if config.strictDepsByDefault then true else stdenv.hostPlatform != stdenv.buildPlatform
, enableParallelBuilding ? config.enableParallelBuildingByDefault
, meta ? {}
, passthru ? {}
, outputs ? [ "out" ]
, sandboxProfile ? ""
, propagatedSandboxProfile ? ""
, hardeningEnable ? []
, hardeningDisable ? []
, patches ? []
, ... } @ attrs: ...
with import <nixpkgs> {};
stdenv.mkDerivation {
name = "my-packge";
dontUnpack = true;
installPhase = ''
mkdir $out
echo "Hello :)" >> $out/message.txt
'';
}
We use name
instead of pname
to avoid having to also set an
explicit version
here.
❤ (theia) ~> nix-build ./message.nix
this derivation will be built:
/nix/store/j5b12i6gabrp868yimgxq2f6sd2prlqi-my-packge.drv
building '/nix/store/j5b12i6gabrp868yimgxq2f6sd2prlqi-my-packge.drv'...
patching sources
configuring
no configure script, doing nothing
building
no Makefile, doing nothing
installing
post-installation fixup
shrinking RPATHs of ELF executables and libraries in /nix/store/4q104yifnnn49gkwcsk4l2y1msc443zh-my-packge
strip is /nix/store/dq0xwmsk1g0i2ayg6pb7y87na2knzylh-gcc-wrapper-11.3.0/bin/strip
patching script interpreter paths in /nix/store/4q104yifnnn49gkwcsk4l2y1msc443zh-my-packge
checking for references to /build/ in /nix/store/4q104yifnnn49gkwcsk4l2y1msc443zh-my-packge...
/nix/store/4q104yifnnn49gkwcsk4l2y1msc443zh-my-packge
❤ (theia) ~> cat /nix/store/357fxrxpqcbrczdq0yfiijq6yn5igq7r-my-packge/message.txt
Hello :)
Any additional key passed to mkDerivation
is set as an
environment variable in the build environment
Some of these variables are used by Nix builds internally (for
example dontUnpack
). Everything else is up to you.
- Find
nixpkgs
on your system (type<nixpkgs>
in the repl) nixpkgs/pkgs/stdenv/generic/setup.sh
- dontUnpack (default
true
) - dontPatch (default
true
) - dontConfigure (default
true
) - dontBuild (default
true
) - doCheck (default
false
) - dontInstall (default
true
) - dontFixup (default
true
) - doInstallCheck (default
false
) - doDist (default
false
)
Importantly: some of these defaults are different based on what builder is invoking them (more on that later)
Some more useful things: https://nixos.org/manual/nix/stable/language/advanced-attributes.html