Home Explore Blog CI



nixpkgs

2nd chunk of `doc/stdenv/multiple-output.chapter.md`
bd835c5f25851a21947042b33a98f3910b1c4c8f1df8d0a30000000100000a8a
In nixpkgs there is a framework supporting multiple-output derivations. It tries to cover most cases by default behavior. You can find the source separated in `<nixpkgs/pkgs/build-support/setup-hooks/multiple-outputs.sh>`; it’s relatively well-readable. The whole machinery is triggered by defining the `outputs` attribute to contain the list of desired output names (strings).

```nix
{
  outputs = [
    "bin"
    "dev"
    "out"
    "doc"
  ];
}
```

Often such a single line is enough. For each output an equally named environment variable is passed to the builder and contains the path in nix store for that output. Typically you also want to have the main `out` output, as it catches any files that didn’t get elsewhere.

::: {.note}
There is a special handling of the `debug` output, described at [](#stdenv-separateDebugInfo).
:::

### “Binaries first” {#multiple-output-file-binaries-first-convention}

A commonly adopted convention in `nixpkgs` is that executables provided by the package are contained within its first output. This convention allows the dependent packages to reference the executables provided by packages in a uniform manner. For instance, provided with the knowledge that the `perl` package contains a `perl` executable it can be referenced as `${pkgs.perl}/bin/perl` within a Nix derivation that needs to execute a Perl script.

The `glibc` package is a deliberate single exception to the “binaries first” convention. The `glibc` has `libs` as its first output allowing the libraries provided by `glibc` to be referenced directly (e.g. `${glibc}/lib/ld-linux-x86-64.so.2`). The executables provided by `glibc` can be accessed via its `bin` attribute (e.g. `${lib.getBin stdenv.cc.libc}/bin/ldd`).

The reason for why `glibc` deviates from the convention is because referencing a library provided by `glibc` is a very common operation among Nix packages. For instance, third-party executables packaged by Nix are typically patched and relinked with the relevant version of `glibc` libraries from Nix packages (please see the documentation on [patchelf](https://github.com/NixOS/patchelf) for more details).

### File type groups {#multiple-output-file-type-groups}

The support code currently recognizes some particular kinds of outputs and either instructs the build system of the package to put files into their desired outputs or it moves the files during the fixup phase. Each group of file types has an `outputFoo` variable specifying the output name where they should go. If that variable isn’t defined by the derivation writer, it is guessed – a default output name is defined, falling back to other possibilities if the output isn’t defined.

Title: Writing Split Derivations and File Type Groups
Summary
Nixpkgs provides a framework for multiple-output derivations, triggered by defining the `outputs` attribute. Each output gets a corresponding environment variable with its path in the Nix store. A convention is to put executables in the first output for easy referencing, exemplified by `${pkgs.perl}/bin/perl`. Glibc is an exception, placing libraries in its first output. The support code recognizes certain output types and moves files accordingly during the fixup phase, using `outputFoo` variables to specify the desired output name. If undefined, it guesses the output, falling back to defaults.