3.4. Phases

The generic builder has 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). Furthermore, it allows a nicer presentation of build logs in the Nix build farm.

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.

There are a number of variables that control what phases are executed and in what order:

The unpack phase is responsible for unpacking the source code of the package. The default implementation of unpackPhase unpacks the source files listed in the src environment variable to the current directory. It supports the following files by default:

Additional file types can be supported by setting the unpackCmd variable (see below).

The patch phase applies the list of patches defined in the patches variable.

The configure phase prepares the source tree for building. The default configurePhase runs ./configure (typically an Autoconf-generated script) if it exists.

Variables controlling the configure phase

configureScript

The name of the configure script. It defaults to ./configure if it exists; otherwise, the configure phase is skipped. This can actually be a command (like perl ./Configure.pl).

configureFlags

A list of strings passed as additional arguments to the configure script.

configureFlagsArray

A shell array containing additional arguments passed to the configure script. You must use this instead of configureFlags if the arguments contain spaces.

dontAddPrefix

By default, the flag --prefix=$prefix is added to the configure flags. If this is undesirable, set this variable to true.

prefix

The prefix under which the package must be installed, passed via the --prefix option to the configure script. It defaults to $out.

dontAddDisableDepTrack

By default, the flag --disable-dependency-tracking is added to the configure flags to speed up Automake-based builds. If this is undesirable, set this variable to true.

dontFixLibtool

By default, the configure phase applies some special hackery to all files called ltmain.sh before running the configure script in order to improve the purity of Libtool-based packages[1]. If this is undesirable, set this variable to true.

dontDisableStatic

By default, when the configure script has --enable-static, the option --disable-static is added to the configure flags.

If this is undesirable, set this variable to true.

preConfigure

Hook executed at the start of the configure phase.

postConfigure

Hook executed at the end of the configure phase.

The build phase is responsible for actually building the package (e.g. compiling it). The default buildPhase simply calls make if a file named Makefile, makefile or GNUmakefile exists in the current directory (or the makefile is explicitly set); otherwise it does nothing.

You can set flags for make through the makeFlags variable.

Before and after running make, the hooks preBuild and postBuild are called, respectively.

The check phase checks whether the package was built correctly by running its test suite. The default checkPhase calls make check, but only if the doCheck variable is enabled.

The install phase is responsible for installing the package in the Nix store under out. The default installPhase creates the directory $out and calls make install.

The fixup phase performs some (Nix-specific) post-processing actions on the files installed under $out by the install phase. The default fixupPhase does the following:

Variables controlling the fixup phase

dontStrip

If set, libraries and executables are not stripped. By default, they are.

dontMoveSbin

If set, files in $out/sbin are not moved to $out/bin. By default, they are.

stripAllList

List of directories to search for libraries and executables from which all symbols should be stripped. By default, it’s empty. Stripping all symbols is risky, since it may remove not just debug symbols but also ELF information necessary for normal execution.

stripAllFlags

Flags passed to the strip command applied to the files in the directories listed in stripAllList. Defaults to -s (i.e. --strip-all).

stripDebugList

List of directories to search for libraries and executables from which only debugging-related symbols should be stripped. It defaults to lib bin sbin.

stripDebugFlags

Flags passed to the strip command applied to the files in the directories listed in stripDebugList. Defaults to -S (i.e. --strip-debug).

dontPatchELF

If set, the patchelf command is not used to remove unnecessary RPATH entries. Only applies to Linux.

dontPatchShebangs

If set, scripts starting with #! do not have their interpreter paths rewritten to paths in the Nix store.

forceShare

The list of directories that must be moved from $out to $out/share. Defaults to man doc info.

setupHook

A package can export a setup hook by setting this variable. The setup hook, if defined, is copied to $out/nix-support/setup-hook. Environment variables are then substituted in it using substituteAll.

preFixup

Hook executed at the start of the fixup phase.

postFixup

Hook executed at the end of the fixup phase.

separateDebugInfo

If set to true, the standard environment will enable debug information in C/C++ builds. After installation, the debug information will be separated from the executables and stored in the output named debug. (This output is enabled automatically; you don’t need to set the outputs attribute explicitly.) To be precise, the debug information is stored in debug/lib/debug/.build-id/XX/YYYY…, where XXYYYY… is the build ID of the binary — a SHA-1 hash of the contents of the binary. Debuggers like GDB use the build ID to look up the separated debug information.

For example, with GDB, you can add

set debug-file-directory ~/.nix-profile/lib/debug

to ~/.gdbinit. GDB will then be able to find debug information installed via nix-env -i.

The distribution phase is intended to produce a source distribution of the package. The default distPhase first calls make dist, then it copies the resulting source tarballs to $out/tarballs/. This phase is only executed if the attribute doDist is set.



[1] It clears the sys_lib_*search_path variables in the Libtool script to prevent Libtool from using libraries in /usr/lib and such.