Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand derivation examples #9048

Merged
merged 4 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/manual/src/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@
- [output]{#gloss-output}

A [store object] produced by a [derivation].
See [the `outputs` argument to the `derivation` function](@docroot@/language/derivations.md#attr-outputs) for details.

[output]: #gloss-output

Expand Down
229 changes: 168 additions & 61 deletions doc/manual/src/language/derivations.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,98 +8,204 @@ It outputs an attribute set, and produces a [store derivation] as a side effect

[store derivation]: @docroot@/glossary.md#gloss-store-derivation

<!-- FIXME: add a section on output attributes -->

## Input attributes

### Required

- [`name`]{#attr-name} ([String](@docroot@/language/values.md#type-string))

A symbolic name for the derivation.
It is added to the [store derivation]'s [path](@docroot@/glossary.md#gloss-store-path) and its [output paths][output path].

Example: `name = "hello";`
It is added to the [store path] of the corresponding [store derivation] as well as to its [output paths](@docroot@/glossary.md#gloss-output-path).

[store path]: @docroot@/glossary.md#gloss-store-path

> **Example**
>
> ```nix
> derivation {
> name = "hello";
> # ...
> }
> ```
>
> The store derivation's path will be `/nix/store/<hash>-hello.drv`.
> The [output](#attr-outputs) paths will be of the form `/nix/store/<hash>-hello[-<output>]`
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved

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>]`
- [`system`]{#attr-system} ([String](@docroot@/language/values.md#type-string))

The system type on which the [`builder`](#attr-builder) executable is meant to be run.

A necessary condition for Nix to build derivations locally is that the `system` attribute matches the current [`system` configuration option].
It can automatically [build on other platforms](../advanced-topics/distributed-builds.md) by forwarding build requests to other machines.

Examples:

`system = "x86_64-linux";`

`system = builtins.currentSystem;`

[`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.

[`system` configuration option]: @docroot@/command-ref/conf-file.md#conf-system

> **Example**
>
> Declare a derivation to be built on a specific system type:
>
> ```nix
> derivation {
> # ...
> system = "x86_64-linux";
> # ...
> }
> ```

> **Example**
>
> Declare a derivation to be built on the system type that evaluates the expression:
>
> ```nix
> derivation {
> # ...
> system = builtins.currentSystem;
> # ...
> }
> ```
>
> [`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.

- [`builder`]{#attr-builder} ([Path](@docroot@/language/values.md#type-path) | [String](@docroot@/language/values.md#type-string))

Path to an executable that will perform the build.

Examples:

`builder = "/bin/bash";`

`builder = ./builder.sh;`

`builder = "${pkgs.python}/bin/python";`
> **Example**
>
> Use the file located at `/bin/bash` as the builder executable:
>
> ```nix
> derivation {
> # ...
> builder = "/bin/bash";
> # ...
> };
> ```

<!-- -->

> **Example**
>
> Copy a local file to the Nix store for use as the builder executable:
>
> ```nix
> derivation {
> # ...
> builder = ./builder.sh;
> # ...
> };
> ```

<!-- -->

> **Example**
>
> Use a file from another derivation as the builder executable:
>
> ```nix
> let pkgs = import <nixpkgs> {}; in
> derivation {
> # ...
> builder = "${pkgs.python}/bin/python";
> # ...
> };
> ```

### Optional

- [`args`]{#attr-args} ([List](@docroot@/language/values.md#list) of [String](@docroot@/language/values.md#type-string)) Default: `[ ]`
- [`args`]{#attr-args} ([List](@docroot@/language/values.md#list) of [String](@docroot@/language/values.md#type-string))

Default: `[ ]`

Command-line arguments to be passed to the [`builder`](#attr-builder) executable.

Example: `args = [ "-c" "echo hello world > $out" ];`
> **Example**
>
> Pass arguments to Bash to interpret a shell command:
>
> ```nix
> derivation {
> # ...
> builder = "/bin/bash";
> args = [ "-c" "echo hello world > $out" ];
> # ...
> };
> ```

- [`outputs`]{#attr-outputs} ([List](@docroot@/language/values.md#list) of [String](@docroot@/language/values.md#type-string)) Default: `[ "out" ]`
- [`outputs`]{#attr-outputs} ([List](@docroot@/language/values.md#list) of [String](@docroot@/language/values.md#type-string))

Symbolic outputs of the derivation.
Each output name is passed to the [`builder`](#attr-builder) executable as an environment variable with its value set to the corresponding [output path].
Default: `[ "out" ]`

[output path]: @docroot@/glossary.md#gloss-output-path
Symbolic outputs of the derivation.
Each output name is passed to the [`builder`](#attr-builder) executable as an environment variable with its value set to the corresponding [store path].

By default, a derivation produces a single output path called `out`.
However, derivations can produce multiple output paths.
By default, a derivation produces a single output called `out`.
However, derivations can produce multiple outputs.
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.

Examples:

Imagine a library package that provides a dynamic library, header files, and documentation.
A program that links against such a library doesn’t need the header files and documentation at runtime, and it doesn’t need the documentation at build time.
Thus, the library package could specify:

```nix
derivation {
# ...
outputs = [ "lib" "dev" "doc" ];
# ...
}
```

This will cause Nix to pass environment variables `lib`, `dev`, and `doc` to the builder containing the intended store paths of each output.
The builder would typically do something like

```bash
./configure \
--libdir=$lib/lib \
--includedir=$dev/include \
--docdir=$doc/share/doc
```

for an Autoconf-style package.

You can refer to each output of a derivation by selecting it as an attribute, e.g. `myPackage.lib` or `myPackage.doc`.

The first element of `outputs` determines the *default output*.
Therefore, in the given example, `myPackage` is equivalent to `myPackage.lib`.
> **Example**
>
> Imagine a library package that provides a dynamic library, header files, and documentation.
> A program that links against such a library doesn’t need the header files and documentation at runtime, and it doesn’t need the documentation at build time.
> Thus, the library package could specify:
>
> ```nix
> derivation {
> # ...
> outputs = [ "lib" "dev" "doc" ];
> # ...
> }
> ```
>
> This will cause Nix to pass environment variables `lib`, `dev`, and `doc` to the builder containing the intended store paths of each output.
> The builder would typically do something like
>
> ```bash
> ./configure \
> --libdir=$lib/lib \
> --includedir=$dev/include \
> --docdir=$doc/share/doc
> ```
>
> for an Autoconf-style package.

The symbolic name is appended to an output's store path, unless it is `out`.
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved

> **Example**
>
>
> ```nix
> derivation {
> name = "example";
> outputs = [ "lib" "dev" "doc" ];
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
> # ...
> }
> ```
>
> The store derivation path will be `/nix/store/<hash>-example.drv`.
> The output paths will be
> - `/nix/store/<hash>-example-lib`
> - `/nix/store/<hash>-example-dev`
> - `/nix/store/<hash>-example-doc`
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved

You can refer to each output of a derivation by selecting it as an attribute.
The first element of `outputs` determines the *default output* and ends up at the top-level.

> **Example**
>
> Select an output by attribute name:
>
> ```nix
> let
> myPackage = derivation {
> name = "example";
> outputs = [ "lib" "dev" "doc" ];
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved
> # ...
> };
> in myPackage.dev
> ```
>
> SInce `lib` is the first output, `myPackage` is equivalent to `myPackage.lib`.
fricklerhandwerk marked this conversation as resolved.
Show resolved Hide resolved

<!-- FIXME: refer to the output attributes when we have one -->

Expand All @@ -123,15 +229,16 @@ It outputs an attribute set, and produces a [store derivation] as a side effect
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.
present derivation. The environment variable is set to the [store path] of the derivation's default [output](#attr-outputs).

- 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.

<!-- FIXME: add a section on output attributes -->

## Builder execution

The [`builder`](#attr-builder) is executed as follows:
Expand Down
Loading