Home Explore Blog Models CI



nixpkgs

13th chunk of `doc/languages-frameworks/haskell.section.md`
d273ffd2041e5f828374d460d950ff529dd59c367bd653fb0000000100000fbf
The arguments are ordered so that you can easily create helper functions by making
use of currying:

```nix
let
  installManPage = haskell.lib.compose.overrideCabal (drv: {
    postInstall = ''
      ${drv.postInstall or ""}
      install -Dm644 man/${drv.pname}.1 -t "$out/share/man/man1"
    '';
  });

in
installManPage haskellPackages.pnbackup
```

In fact, `haskell.lib.compose` already provides lots of useful helpers for common
tasks, detailed in the next section. They are also structured in such a way that
they can be combined using `lib.pipe`:

```nix
lib.pipe my-haskell-package [
  # lift version bounds on dependencies
  haskell.lib.compose.doJailbreak
  # disable building the haddock documentation
  haskell.lib.compose.dontHaddock
  # pass extra package flag to Cabal's configure step
  (haskell.lib.compose.enableCabalFlag "myflag")
]
```

#### `haskell.lib.compose` {#haskell-haskell.lib.compose}

The base interface for all overriding is the following function:

`overrideCabal f drv`
: Takes the arguments passed to obtain `drv` to `f` and uses the resulting
attribute set to update the argument set. Then a recomputed version of `drv`
using the new argument set is returned.

<!--
TODO(@sternenseemann): ideally we want to be more detailed here as well, but
I want to avoid the documentation having to be kept in sync in too many places.
We already document this stuff in the mkDerivation section and lib/compose.nix.
Ideally this section would be generated from the latter in the future.
-->

All other helper functions are implemented in terms of `overrideCabal` and make
common overrides shorter and more complicate ones trivial. The simple overrides
which only change a single argument are only described very briefly in the
following overview. Refer to the
[documentation of `haskellPackages.mkDerivation`](#haskell-mkderivation)
for a more detailed description of the effects of the respective arguments.

##### Packaging Helpers {#haskell-packaging-helpers}

`overrideSrc { src, version } drv`
: Replace the source used for building `drv` with the path or derivation given
as `src`. The `version` attribute is optional. Prefer this function over
overriding `src` via `overrideCabal`, since it also automatically takes care of
removing any Hackage revisions.

<!-- TODO(@sternenseemann): deprecated

`generateOptparseApplicativeCompletions list drv`
: Generate and install shell completion files for the installed executables whose
names are given via `list`. The executables need to be using `optparse-applicative`
for this to work.
-->

`justStaticExecutables drv`
: Only build and install the executables produced by `drv`, removing everything
  that may refer to other Haskell packages' store paths (like libraries and
  documentation). This dramatically reduces the closure size of the resulting
  derivation. Note that the executables are only statically linked against their
  Haskell dependencies, but will still link dynamically against libc, GMP and
  other system library dependencies.

  If a library or its dependencies use their Cabal-generated
  `Paths_*` module, this may not work as well if GHC's dead code elimination is
  unable to remove the references to the dependency's store path that module
  contains.
  As a consequence, an unused reference may be created from the static binary to such a _library_ store path.
  (See [nixpkgs#164630][164630] for more information.)

  Importing the `Paths_*` module may cause builds to fail with this message:

  ```
  error: output '/nix/store/64k8iw0ryz76qpijsnl9v87fb26v28z8-my-haskell-package-1.0.0.0' is not allowed to refer to the following paths:
           /nix/store/5q5s4a07gaz50h04zpfbda8xjs8wrnhg-ghc-9.6.3
  ```

  If that happens, first disable the check for GHC references and rebuild the
  derivation:

  ```nix
  pkgs.haskell.lib.overrideCabal (pkgs.haskell.lib.justStaticExecutables my-haskell-package) (drv: {
    disallowGhcReference = false;
  })
  ```

  Then use `strings` to determine which libraries are responsible:

Title: Nix Haskell Overrides: `haskell.lib.compose` and Packaging Helpers
Summary
This section elaborates on `haskell.lib.compose`, a collection of helper functions built upon `overrideCabal` that streamline common Haskell package overrides in Nix. It demonstrates how these helpers can be chained using `lib.pipe` for tasks like adjusting dependency version bounds (`doJailbreak`), disabling Haddock documentation (`dontHaddock`), or enabling Cabal flags (`enableCabalFlag`). The core `overrideCabal` function is defined as a mechanism to update derivation arguments and recompute the derivation. Following this, specific packaging helpers are introduced: `overrideSrc` for replacing a package's source and `justStaticExecutables` for building only executables, significantly reducing derivation closure size. A known issue with `justStaticExecutables` and `Paths_*` modules causing GHC reference errors is discussed, along with a workaround using `disallowGhcReference = false`.