Home Explore Blog CI



nixpkgs

10th chunk of `doc/stdenv/stdenv.chapter.md`
620591cdf4c6d4a5c1c33d071b9ee99aea9977ad4fd7e2810000000100000fd5
#### `enableParallelBuilding` {#var-stdenv-enableParallelBuilding}

If set to `true`, `stdenv` will pass specific flags to `make` and other build tools to enable parallel building with up to `build-cores` workers.

Unless set to `false`, some build systems with good support for parallel building including `cmake`, `meson`, and `qmake` will set it to `true`.

### Fixed-point arguments of `mkDerivation` {#mkderivation-recursive-attributes}

If you pass a function to `mkDerivation`, it will receive as its argument the final arguments, including the overrides when reinvoked via `overrideAttrs`. For example:

```nix
mkDerivation (finalAttrs: {
  pname = "hello";
  withFeature = true;
  configureFlags = lib.optionals finalAttrs.withFeature [ "--with-feature" ];
})
```

Note that this does not use the `rec` keyword to reuse `withFeature` in `configureFlags`.
The `rec` keyword works at the syntax level and is unaware of overriding.

Instead, the definition references `finalAttrs`, allowing users to change `withFeature`
consistently with `overrideAttrs`.

`finalAttrs` also contains the attribute `finalPackage`, which includes the output paths, etc.

Let's look at a more elaborate example to understand the differences between
various bindings:

```nix
# `pkg` is the _original_ definition (for illustration purposes)
let
  pkg = mkDerivation (finalAttrs: {
    # ...

    # An example attribute
    packages = [ ];

    # `passthru.tests` is a commonly defined attribute.
    passthru.tests.simple = f finalAttrs.finalPackage;

    # An example of an attribute containing a function
    passthru.appendPackages =
      packages':
      finalAttrs.finalPackage.overrideAttrs (
        newSelf: super: {
          packages = super.packages ++ packages';
        }
      );

    # For illustration purposes; referenced as
    # `(pkg.overrideAttrs(x)).finalAttrs` etc in the text below.
    passthru.finalAttrs = finalAttrs;
    passthru.original = pkg;
  });
in
pkg
```

Unlike the `pkg` binding in the above example, the `finalAttrs` parameter always references the final attributes. For instance `(pkg.overrideAttrs(x)).finalAttrs.finalPackage` is identical to `pkg.overrideAttrs(x)`, whereas `(pkg.overrideAttrs(x)).original` is the same as the original `pkg`.

See also the section about [`passthru.tests`](#var-passthru-tests).

## Phases {#sec-stdenv-phases}

`stdenv.mkDerivation` sets the Nix [derivation](https://nixos.org/manual/nix/stable/expressions/derivations.html#derivations)'s builder to a script that loads the stdenv `setup.sh` bash library and calls `genericBuild`. Most packaging functions rely on this default builder.

This generic command either invokes a script at *buildCommandPath*, or a *buildCommand*, or a number of *phases*. Package builds are split into phases to make it easier to override specific parts of the build (e.g., unpacking the sources or installing the binaries).

Each phase can be overridden in its entirety either by setting the environment variable `namePhase` to a string containing some shell commands to be executed, or by redefining the shell function `namePhase`. The former is convenient to override a phase from the derivation, while the latter is convenient from a build script. However, typically one only wants to *add* some commands to a phase, e.g. by defining `postInstall` or `preFixup`, as skipping some of the default actions may have unexpected consequences. The default script for each phase is defined in the file `pkgs/stdenv/generic/setup.sh`.

When overriding a phase, for example `installPhase`, it is important to start with `runHook preInstall` and end it with `runHook postInstall`, otherwise `preInstall` and `postInstall` will not be run. Even if you don't use them directly, it is good practice to do so anyways for downstream users who would want to add a `postInstall` by overriding your derivation.

While inside an interactive `nix-shell`, if you wanted to run all phases in the order they would be run in an actual build, you can invoke `genericBuild` yourself.

Title: Parallel Building, mkDerivation Fixed-Point Arguments, and Build Phases
Summary
This section describes `enableParallelBuilding` for enabling parallel builds, how `mkDerivation` passes final arguments including overrides, and explains the concept of build phases in `stdenv.mkDerivation`. It details how package builds are split into phases, how to override them, and the importance of using `runHook preInstall` and `runHook postInstall` when overriding phases. It also mentions how to run all phases in an interactive `nix-shell` using `genericBuild`.