Merge pull request #7320 from fricklerhandwerk/doc-derivation

restructure attribute listing to `derivation`
This commit is contained in:
Valentin Gagarin 2023-09-26 01:42:07 +02:00 committed by GitHub
commit b7d88fe56a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,161 +1,200 @@
# Derivations # Derivations
The most important built-in function is `derivation`, which is used to The most important built-in function is `derivation`, which is used to describe a single derivation:
describe a single derivation (a build task). It takes as input a set, a specification for running an executable on precisely defined input files to repeatably produce output files at uniquely determined file system paths.
the attributes of which specify the inputs of the build.
- There must be an attribute named [`system`]{#attr-system} whose value must be a It takes as input an attribute set, the attributes of which specify the inputs to the process.
string specifying a Nix system type, such as `"i686-linux"` or It outputs an attribute set, and produces a [store derivation](@docroot@/glossary.md#gloss-store-derivation) as a side effect of evaluation.
`"x86_64-darwin"`. (To figure out your system type, run `nix -vv
--version`.) The build can only be performed on a machine and
operating system matching the system type. (Nix can automatically
[forward builds for other
platforms](../advanced-topics/distributed-builds.md) by forwarding
them to other machines.)
- There must be an attribute named `name` whose value must be a <!-- FIXME: add a section on output attributes -->
string. This is used as a symbolic name for the package by
`nix-env`, and it is appended to the output paths of the derivation.
- There must be an attribute named [`builder`]{#attr-builder} that identifies the ## Input attributes
program that is executed to perform the build. It can be either a
derivation or a source (a local file reference, e.g.,
`./builder.sh`).
- Every attribute is passed as an environment variable to the builder. ### Required
Attribute values are translated to environment variables as follows:
- Strings and numbers are just passed verbatim. - [`name`]{#attr-name} ([String](@docroot@/language/values.md#type-string))
- A *path* (e.g., `../foo/sources.tar`) causes the referenced file A symbolic name for the derivation.
to be copied to the store; its location in the store is put in It is added to the [store derivation]'s [path](@docroot@/glossary.md#gloss-store-path) and its [output paths][output path].
the environment variable. The idea is that all sources should
reside in the Nix store, since all inputs to a derivation should
reside in the Nix store.
- A *derivation* causes that derivation to be built prior to the Example: `name = "hello";`
present derivation; its default output path is put in the
environment variable.
- Lists of the previous types are also allowed. They are simply The store derivation's path will be `/nix/store/<hash>-hello.drv`, and the output paths will be of the form `/nix/store/<hash>-hello[-<output>]`
concatenated, separated by spaces. - [`system`]{#attr-system} ([String](@docroot@/language/values.md#type-string))
- `true` is passed as the string `1`, `false` and `null` are The system type on which the [`builder`](#attr-builder) executable is meant to be run.
passed as an empty string.
- The optional attribute `args` specifies command-line arguments to be A necessary condition for Nix to build derivations locally is that the `system` attribute matches the current [`system` configuration option].
passed to the builder. It should be a list. It can automatically [build on other platforms](../advanced-topics/distributed-builds.md) by forwarding build requests to other machines.
- The optional attribute `outputs` specifies a list of symbolic Examples:
outputs of the derivation. By default, a derivation produces a
single output path, denoted as `out`. However, derivations can
produce multiple output paths. This is useful because it allows
outputs to be downloaded or garbage-collected separately. For
instance, imagine a library package that provides a dynamic library,
header files, and documentation. A program that links against the
library doesnt need the header files and documentation at runtime,
and it doesnt need the documentation at build time. Thus, the
library package could specify:
```nix `system = "x86_64-linux";`
outputs = [ "lib" "headers" "doc" ];
```
This will cause Nix to pass environment variables `lib`, `headers` `system = builtins.currentSystem;`
and `doc` to the builder containing the intended store paths of each
output. The builder would typically do something like
```bash [`builtins.currentSystem`](@docroot@/language/builtin-constants.md#builtins-currentSystem) has the value of the [`system` configuration option], and defaults to the system type of the current Nix installation.
./configure \
--libdir=$lib/lib \
--includedir=$headers/include \
--docdir=$doc/share/doc
```
for an Autoconf-style package. You can refer to each output of a [`system` configuration option]: @docroot@/command-ref/conf-file.md#conf-system
derivation by selecting it as an attribute, e.g.
```nix - [`builder`]{#attr-builder} ([Path](@docroot@/language/values.md#type-path) | [String](@docroot@/language/values.md#type-string))
buildInputs = [ pkg.lib pkg.headers ];
```
The first element of `outputs` determines the *default output*. Path to an executable that will perform the build.
Thus, you could also write
```nix Examples:
buildInputs = [ pkg pkg.headers ];
```
since `pkg` is equivalent to `pkg.lib`. `builder = "/bin/bash";`
The function `mkDerivation` in the Nixpkgs standard environment is a `builder = ./builder.sh;`
wrapper around `derivation` that adds a default value for `system` and
always uses Bash as the builder, to which the supplied builder is passed
as a command-line argument. See the Nixpkgs manual for details.
The builder is executed as follows: `builder = "${pkgs.python}/bin/python";`
- A temporary directory is created under the directory specified by ### Optional
`TMPDIR` (default `/tmp`) where the build will take place. The
current directory is changed to this directory.
- The environment is cleared and set to the derivation attributes, as - [`args`]{#attr-args} ([List](@docroot@/language/values.md#list) of [String](@docroot@/language/values.md#type-string)) Default: `[ ]`
specified above.
- In addition, the following variables are set: Command-line arguments to be passed to the [`builder`](#attr-builder) executable.
- `NIX_BUILD_TOP` contains the path of the temporary directory for Example: `args = [ "-c" "echo hello world > $out" ];`
this build.
- Also, `TMPDIR`, `TEMPDIR`, `TMP`, `TEMP` are set to point to the - [`outputs`]{#attr-outputs} ([List](@docroot@/language/values.md#list) of [String](@docroot@/language/values.md#type-string)) Default: `[ "out" ]`
temporary directory. This is to prevent the builder from
accidentally writing temporary files anywhere else. Doing so
might cause interference by other processes.
- `PATH` is set to `/path-not-set` to prevent shells from Symbolic outputs of the derivation.
initialising it to their built-in default value. Each output name is passed to the [`builder`](#attr-builder) executable as an environment variable with its value set to the corresponding [output path].
- `HOME` is set to `/homeless-shelter` to prevent programs from [output path]: @docroot@/glossary.md#gloss-output-path
using `/etc/passwd` or the like to find the user's home
directory, which could cause impurity. Usually, when `HOME` is
set, it is used as the location of the home directory, even if
it points to a non-existent path.
- `NIX_STORE` is set to the path of the top-level Nix store By default, a derivation produces a single output path called `out`.
directory (typically, `/nix/store`). However, derivations can produce multiple output paths.
This allows the associated [store objects](@docroot@/glossary.md#gloss-store-object) and their [closures](@docroot@/glossary.md#gloss-closure) to be copied or garbage-collected separately.
- For each output declared in `outputs`, the corresponding Examples:
environment variable is set to point to the intended path in the
Nix store for that output. Each output path is a concatenation
of the cryptographic hash of all build inputs, the `name`
attribute and the output name. (The output name is omitted if
its `out`.)
- If an output path already exists, it is removed. Also, locks are Imagine a library package that provides a dynamic library, header files, and documentation.
acquired to prevent multiple Nix instances from performing the same A program that links against such a library doesnt need the header files and documentation at runtime, and it doesnt need the documentation at build time.
build at the same time. Thus, the library package could specify:
- A log of the combined standard output and error is written to ```nix
`/nix/var/log/nix`. derivation {
# ...
outputs = [ "lib" "dev" "doc" ];
# ...
}
```
- The builder is executed with the arguments specified by the This will cause Nix to pass environment variables `lib`, `dev`, and `doc` to the builder containing the intended store paths of each output.
attribute `args`. If it exits with exit code 0, it is considered to The builder would typically do something like
have succeeded.
- The temporary directory is removed (unless the `-K` option was ```bash
specified). ./configure \
--libdir=$lib/lib \
--includedir=$dev/include \
--docdir=$doc/share/doc
```
- If the build was successful, Nix scans each output path for for an Autoconf-style package.
references to input paths by looking for the hash parts of the input
paths. Since these are potential runtime dependencies, Nix registers
them as dependencies of the output paths.
- After the build, Nix sets the last-modified timestamp on all files You can refer to each output of a derivation by selecting it as an attribute, e.g. `myPackage.lib` or `myPackage.doc`.
in the build result to 1 (00:00:01 1/1/1970 UTC), sets the group to
the default group, and sets the mode of the file to 0444 or 0555 The first element of `outputs` determines the *default output*.
(i.e., read-only, with execute permission enabled if the file was Therefore, in the given example, `myPackage` is equivalent to `myPackage.lib`.
originally executable). Note that possible `setuid` and `setgid`
bits are cleared. Setuid and setgid programs are not currently <!-- FIXME: refer to the output attributes when we have one -->
supported by Nix. This is because the Nix archives used in
deployment have no concept of ownership information, and because it - See [Advanced Attributes](./advanced-attributes.md) for more, infrequently used, optional attributes.
makes the build result dependent on the user performing the build.
<!-- FIXME: This should be moved here -->
- Every other attribute is passed as an environment variable to the builder.
Attribute values are translated to environment variables as follows:
- Strings are passed unchanged.
- Integral numbers are converted to decimal notation.
- Floating point numbers are converted to simple decimal or scientific notation with a preset precision.
- A *path* (e.g., `../foo/sources.tar`) causes the referenced file
to be copied to the store; its location in the store is put in
the environment variable. The idea is that all sources should
reside in the Nix store, since all inputs to a derivation should
reside in the Nix store.
- A *derivation* causes that derivation to be built prior to the
present derivation; its default output path is put in the
environment variable.
- Lists of the previous types are also allowed. They are simply
concatenated, separated by spaces.
- `true` is passed as the string `1`, `false` and `null` are
passed as an empty string.
## Builder execution
The [`builder`](#attr-builder) is executed as follows:
- A temporary directory is created under the directory specified by
`TMPDIR` (default `/tmp`) where the build will take place. The
current directory is changed to this directory.
- The environment is cleared and set to the derivation attributes, as
specified above.
- In addition, the following variables are set:
- `NIX_BUILD_TOP` contains the path of the temporary directory for
this build.
- Also, `TMPDIR`, `TEMPDIR`, `TMP`, `TEMP` are set to point to the
temporary directory. This is to prevent the builder from
accidentally writing temporary files anywhere else. Doing so
might cause interference by other processes.
- `PATH` is set to `/path-not-set` to prevent shells from
initialising it to their built-in default value.
- `HOME` is set to `/homeless-shelter` to prevent programs from
using `/etc/passwd` or the like to find the user's home
directory, which could cause impurity. Usually, when `HOME` is
set, it is used as the location of the home directory, even if
it points to a non-existent path.
- `NIX_STORE` is set to the path of the top-level Nix store
directory (typically, `/nix/store`).
- For each output declared in `outputs`, the corresponding
environment variable is set to point to the intended path in the
Nix store for that output. Each output path is a concatenation
of the cryptographic hash of all build inputs, the `name`
attribute and the output name. (The output name is omitted if
its `out`.)
- If an output path already exists, it is removed. Also, locks are
acquired to prevent multiple Nix instances from performing the same
build at the same time.
- A log of the combined standard output and error is written to
`/nix/var/log/nix`.
- The builder is executed with the arguments specified by the
attribute `args`. If it exits with exit code 0, it is considered to
have succeeded.
- The temporary directory is removed (unless the `-K` option was
specified).
- If the build was successful, Nix scans each output path for
references to input paths by looking for the hash parts of the input
paths. Since these are potential runtime dependencies, Nix registers
them as dependencies of the output paths.
- After the build, Nix sets the last-modified timestamp on all files
in the build result to 1 (00:00:01 1/1/1970 UTC), sets the group to
the default group, and sets the mode of the file to 0444 or 0555
(i.e., read-only, with execute permission enabled if the file was
originally executable). Note that possible `setuid` and `setgid`
bits are cleared. Setuid and setgid programs are not currently
supported by Nix. This is because the Nix archives used in
deployment have no concept of ownership information, and because it
makes the build result dependent on the user performing the build.