about summary refs log tree commit diff
path: root/doc/languages-frameworks
diff options
context:
space:
mode:
authorRebecca Turner <rbt@sent.as>2023-04-28 10:04:05 -0700
committerRebecca Turner <rbt@sent.as>2023-05-25 14:36:18 -0700
commitec2938bfa5f98b43e5f87ba510ba3cdebaa16496 (patch)
treeadf041b0ad244225b3c37f87e5f1ff1456bb7b8a /doc/languages-frameworks
parent1535bd0c58e0f7a093bea8d15e37f0cc1a719db2 (diff)
Document incremental build support for Haskell
Diffstat (limited to 'doc/languages-frameworks')
-rw-r--r--doc/languages-frameworks/haskell.section.md71
1 files changed, 71 insertions, 0 deletions
diff --git a/doc/languages-frameworks/haskell.section.md b/doc/languages-frameworks/haskell.section.md
index a36843c97c61e..894eba1494e5a 100644
--- a/doc/languages-frameworks/haskell.section.md
+++ b/doc/languages-frameworks/haskell.section.md
@@ -276,6 +276,15 @@ Defaults to `true`.
 : Whether to generate an index for interactive navigation of the HTML documentation.
 Defaults to `true` if supported.
 
+`doInstallIntermediates`
+: Whether to install intermediate build products (files written to `dist/build`
+by GHC during the build process). With `enableSeparateIntermediatesOutput`,
+these files are instead installed to [a separate `intermediates`
+output.][multiple-outputs] The output can then be passed into a future build of
+the same package with the `previousIntermediates` argument to support
+incremental builds. See [“Incremental builds”](#haskell-incremental-builds) for
+more information. Defaults to `false`.
+
 `enableLibraryProfiling`
 : Whether to enable [profiling][profiling] for libraries contained in the
 package. Enabled by default if supported.
@@ -371,6 +380,12 @@ Defaults to `false`.
 : Whether to install documentation to a separate `doc` output.
 Is automatically enabled if `doHaddock` is `true`.
 
+`enableSeparateIntermediatesOutput`
+: When `doInstallIntermediates` is true, whether to install intermediate build
+products to a separate `intermediates` output. See [“Incremental
+builds”](#haskell-incremental-builds) for more information. Defaults to
+`false`.
+
 `allowInconsistentDependencies`
 : If enabled, allow multiple versions of the same Haskell package in the
 dependency tree at configure time. Often in such a situation compilation would
@@ -381,6 +396,11 @@ later fail because of type mismatches. Defaults to `false`.
 when loading the library in the REPL, but requires extra build time and
 disk space. Defaults to `false`.
 
+`previousIntermediates`
+: If non-null, intermediate build artifacts are copied from this input to
+`dist/build` before performing compiling. See [“Incremental
+builds”](#haskell-incremental-builds) for more information. Defaults to `null`.
+
 `buildTarget`
 : Name of the executable or library to build and install.
 If unset, all available targets are built and installed.
@@ -496,6 +516,54 @@ the [Meta-attributes section](#chap-meta) for their documentation.
     * `broken`
     * `hydraPlatforms`
 
+### 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
@@ -1083,8 +1151,11 @@ on the issue linked above.
 [haskell.nix]: https://input-output-hk.github.io/haskell.nix/index.html
 [HLS user guide]: https://haskell-language-server.readthedocs.io/en/latest/configuration.html#configuring-your-editor
 [hoogle]: https://wiki.haskell.org/Hoogle
+[incremental-builds]: https://www.haskellforall.com/2022/12/nixpkgs-support-for-incremental-haskell.html
 [jailbreak-cabal]: https://github.com/NixOS/jailbreak-cabal/
+[multiple-outputs]: https://nixos.org/manual/nixpkgs/stable/#chap-multiple-output
 [optparse-applicative-completions]: https://github.com/pcapriotti/optparse-applicative/blob/7726b63796aa5d0df82e926d467f039b78ca09e2/README.md#bash-zsh-and-fish-completions
 [profiling-detail]: https://cabal.readthedocs.io/en/latest/cabal-project.html#cfg-field-profiling-detail
 [profiling]: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html
 [search.nixos.org]: https://search.nixos.org
+[turtle]: https://hackage.haskell.org/package/turtle