Home Explore Blog CI



nixpkgs

8th chunk of `doc/languages-frameworks/haskell.section.md`
623a5ae25a07a7a1c6275f79858fa40bdb54c839e64cabe50000000100000fd6
### Incremental builds {#haskell-incremental-builds}

`haskellPackages.mkDerivation` supports incremental builds for GHC 9.4 and
newer with the `doInstallIntermediates`, `enableSeparateIntermediatesOutput`,
and `previousIntermediates` arguments.

The basic idea is to first perform a full build of the package in question,
save its intermediate build products for later, and then copy those build
products into the build directory of an incremental build performed later.
Then, GHC will use those build artifacts to avoid recompiling unchanged
modules.

For more detail on how to store and use incremental build products, see
[Gabriella Gonzalez’ blog post “Nixpkgs support for incremental Haskell
builds”.][incremental-builds] motivation behind this feature.

An incremental build for [the `turtle` package][turtle] can be performed like
so:

```nix
let
  pkgs = import <nixpkgs> { };
  inherit (pkgs) haskell;
  inherit (haskell.lib.compose) overrideCabal;

  # Incremental builds work with GHC >=9.4.
  turtle = haskell.packages.ghc944.turtle;

  # This will do a full build of `turtle`, while writing the intermediate build products
  # (compiled modules, etc.) to the `intermediates` output.
  turtle-full-build-with-incremental-output = overrideCabal (drv: {
    doInstallIntermediates = true;
    enableSeparateIntermediatesOutput = true;
  }) turtle;

  # This will do an incremental build of `turtle` by copying the previously
  # compiled modules and intermediate build products into the source tree
  # before running the build.
  #
  # GHC will then naturally pick up and reuse these products, making this build
  # complete much more quickly than the previous one.
  turtle-incremental-build = overrideCabal (drv: {
    previousIntermediates = turtle-full-build-with-incremental-output.intermediates;
  }) turtle;
in
turtle-incremental-build
```

## Development environments {#haskell-development-environments}

In addition to building and installing Haskell software, nixpkgs can also
provide development environments for Haskell projects. This has the obvious
advantage that you benefit from `cache.nixos.org` and no longer need to compile
all project dependencies yourself. While it is often very useful, this is not
the primary use case of our package set. Have a look at the section
[available package versions](#haskell-available-versions) to learn which
versions of packages we provide and the section
[limitations](#haskell-limitations), to judge whether a `haskellPackages`
based development environment for your project is feasible.

By default, every derivation built using
[`haskellPackages.mkDerivation`](#haskell-mkderivation) exposes an environment
suitable for building it interactively as the `env` attribute. For example, if
you have a local checkout of `random`, you can enter a development environment
for it like this (if the dependencies in the development and packaged version
match):

```console
$ cd ~/src/random
$ nix-shell -A haskellPackages.random.env '<nixpkgs>'
[nix-shell:~/src/random]$ ghc-pkg list
/nix/store/a8hhl54xlzfizrhcf03c1l3f6l9l8qwv-ghc-9.2.4-with-packages/lib/ghc-9.2.4/package.conf.d
    Cabal-3.6.3.0
    array-0.5.4.0
    base-4.16.3.0
    binary-0.8.9.0
    …
    ghc-9.2.4
    …
```

As you can see, the environment contains a GHC which is set up so it finds all
dependencies of `random`. Note that this environment does not mirror
the environment used to build the package, but is intended as a convenient
tool for development and simple debugging. `env` relies on the `ghcWithPackages`
wrapper which automatically injects a pre-populated package-db into every
GHC invocation. In contrast, using `nix-shell -A haskellPackages.random` will
not result in an environment in which the dependencies are in GHCs package
database. Instead, the Haskell builder will pass in all dependencies explicitly
via configure flags.

`env` mirrors the normal derivation environment in one aspect: It does not include
familiar development tools like `cabal-install`, since we rely on plain `Setup.hs`

Title: Incremental Builds and Development Environments
Summary
This section details how to use incremental builds in `haskellPackages.mkDerivation` for GHC 9.4+, using `doInstallIntermediates`, `enableSeparateIntermediatesOutput`, and `previousIntermediates`. It provides an example with the `turtle` package, demonstrating how to perform a full build and then an incremental build using the intermediate outputs. The section also discusses setting up Haskell development environments with nixpkgs, using the `env` attribute of derivations built with `haskellPackages.mkDerivation` for interactive building. It highlights the differences between using `env` and directly using `nix-shell` with a package, noting that `env` provides a GHC with pre-populated dependencies.