Home Explore Blog CI



nixpkgs

1st chunk of `doc/stdenv/stdenv.chapter.md`
cf02c35d39cd1ffdab71e8b4ffe6243e53d8340ca565c3190000000100000fbc
# The Standard Environment {#chap-stdenv}

The standard build environment in the Nix Packages collection provides an environment for building Unix packages that does a lot of common build tasks automatically. In fact, for Unix packages that use the standard `./configure; make; make install` build interface, you don’t need to write a build script at all; the standard environment does everything automatically. If `stdenv` doesn’t do what you need automatically, you can easily customise or override the various build phases.

## Using `stdenv` {#sec-using-stdenv}

To build a package with the standard environment, you use the function `stdenv.mkDerivation`, instead of the primitive built-in function `derivation`, e.g.

```nix
stdenv.mkDerivation {
  name = "libfoo-1.2.3";
  src = fetchurl {
    url = "http://example.org/libfoo-1.2.3.tar.bz2";
    hash = "sha256-tWxU/LANbQE32my+9AXyt3nCT7NBVfJ45CX757EMT3Q=";
  };
}
```

(`stdenv` needs to be in scope, so if you write this in a separate Nix expression from `pkgs/all-packages.nix`, you need to pass it as a function argument.) Specifying a `name` and a `src` is the absolute minimum Nix requires. For convenience, you can also use `pname` and `version` attributes and `mkDerivation` will automatically set `name` to `"${pname}-${version}"` by default.
**Since [RFC 0035](https://github.com/NixOS/rfcs/pull/35), this is preferred for packages in Nixpkgs**, as it allows us to reuse the version easily:

```nix
stdenv.mkDerivation (finalAttrs: {
  pname = "libfoo";
  version = "1.2.3";
  src = fetchurl {
    url = "http://example.org/libfoo-source-${finalAttrs.version}.tar.bz2";
    hash = "sha256-tWxU/LANbQE32my+9AXyt3nCT7NBVfJ45CX757EMT3Q=";
  };
})
```

Many packages have dependencies that are not provided in the standard environment. It’s usually sufficient to specify those dependencies in the `buildInputs` attribute:

```nix
stdenv.mkDerivation {
  pname = "libfoo";
  version = "1.2.3";
  # ...
  buildInputs = [
    libbar
    perl
    ncurses
  ];
}
```

This attribute ensures that the `bin` subdirectories of these packages appear in the `PATH` environment variable during the build, that their `include` subdirectories are searched by the C compiler, and so on. (See [](#ssec-setup-hooks) for details.)

Often it is necessary to override or modify some aspect of the build. To make this easier, the standard environment breaks the package build into a number of *phases*, all of which can be overridden or modified individually: unpacking the sources, applying patches, configuring, building, and installing. (There are some others; see [](#sec-stdenv-phases).) For instance, a package that doesn’t supply a makefile but instead has to be compiled "manually" could be handled like this:

```nix
stdenv.mkDerivation {
  pname = "fnord";
  version = "4.5";

  # ...

  buildPhase = ''
    runHook preBuild

    gcc foo.c -o foo

    runHook postBuild
  '';

  installPhase = ''
    runHook preInstall

    mkdir -p $out/bin
    cp foo $out/bin

    runHook postInstall
  '';
}
```

(Note the use of `''`-style string literals, which are very convenient for large multi-line script fragments because they don’t need escaping of `"` and `\`, and because indentation is intelligently removed.)

There are many other attributes to customise the build. These are listed in [](#ssec-stdenv-attributes).

While the standard environment provides a generic builder, you can still supply your own build script:

```nix
stdenv.mkDerivation {
  pname = "libfoo";
  version = "1.2.3";
  # ...
  builder = ./builder.sh;
}
```

where `stdenv` sets up the environment automatically (e.g. by resetting `PATH` and populating it from build inputs). If you want, you can use `stdenv`’s generic builder:

```bash
buildPhase() {
  echo "... this is my custom build phase ..."
  gcc foo.c -o foo
}

installPhase() {
  mkdir -p $out/bin
  cp foo $out/bin
}

genericBuild
```

### Building a `stdenv` package in `nix-shell` {#sec-building-stdenv-package-in-nix-shell}

Title: The Standard Environment in Nix Packages
Summary
The standard build environment in the Nix Packages collection provides an environment for building Unix packages and automates common build tasks. It uses `stdenv.mkDerivation` function to build packages. It automatically handles packages that use the standard `./configure; make; make install` build interface. The environment can be customized, build phases can be overridden, and dependencies can be specified. It also provides a generic builder, but users can supply their own build script if needed.