Learning Nix - Nixpkgs standard environment

25/04/2023

Explaining the build process with nixpkgs.stdenv

In the previous post, we saw the basic syntax of Nix and learned about derivations.

The built-in function derivation makes it possible to define a derivation, given at least a name, a system and an executable to build the package.

In practice however, you still need the builder logic, for instance: unpack the source, then ./configure; make; make install. For a lot of packages, this builder logic will be similar, hence the stdenv package.

The setup.sh script

Most of the logic necessary to build and install autotools packages is inside this script.

First, it clears the PATH and fills it with a couple of useful tools 1, such as the GNU coreutils, tar, make, grep, etc.

Then, it defines the following bash functions:

Finally, it defines the genericBuild function which calls all these phases successively, plus any pre/post hooks defined for each phase 2.

This script is an output of the stdenv derivation, which means that you can use it to reproduce the build environment, and debug your package step-by-step manually.

The stdenv.mkDerivation function

In practice, most packages do not directly use the derivation function but rather the mkDerivation function, defined in the stdenv package.

This wrapper around the builtin derivation conveniently sets some attributes of the output derivation:

Also, it sets the name and system attributes (using provided pname/version or name, and stdenv.buildPlatform.system).



  1. At time of writing, this list of tools is more or less defined in common-path.nix, and passed to setup.sh via the initialPath env variable (see e.g. stdenv/nix/default.nix). 

  2. A couple additional functions are defined, even though they are disabled by default: checkPhase to run tests (calls make check), installCheckPhaseto run tests against the installed directories (calls make installcheck), and distPhase to produce a source distribution of the package (calls make dist). These phases can be activated by setting doCheck, doInstallCheck or doDist to true, if the Makefile exists.