haskell.nix

haskell.nix is an alternative Haskell infrastructure for Nix1.

Features

  • Drop-in support for Cabal projects
  • Drop-in support for Stack projects
  • Build any package of specific version in Stackage or Hackage
  • Overridable configuration
  • Cross compile Haskell packages

Motivation

Why do we need another Haskell infrastructure for Nix?

Doesn't nixpkgs provide a sufficiently good Haskell infrastructure already?

Problems with the nixpkgs haskell infrastructure are covered in the following sections:

Cross compilation

nixpkgs has quite good support for cross compilation, however the Haskell infrastructure suffers from the fact that it heavily relies on the cabal2nix tool. cabal2nix (as well as tools that depend on it like stack2nix) flattens the .cabal file at conversion time to a given os/arch/flags configuration. Thus to make cross compilation work with cabal2nix you will have to generate a separate nix expression for each configuration. This becomes a major maintenance burden over time. Therefore the tooling that translates cabal files into nix-expressions for use with Haskell.nix retains the full conditional tree from the cabal file and exposes it to nix. In addition it will also expose the build-type value, which allows us to cache the Setup.hs for build-type simple and not have to rebuild it every time.

Package sets

We often rely on either package sets as provided by stackage or computed by cabal. nixpkgs provides its own curated package set which might or might not work for the projects we work on. stack2nix tries to solve this issue, here we go one step further and provide the infrastructure to allow any form of package set.

Per component level control

The Haskell builder in nixpkgs provides control over executables and libraries, to build a specific executable only however is rather tricky to do. This also leads to the cyclic dependencies issue.

Cyclic dependencies

The Haskell builder in nixpkgs exposes packages at the package level. If packages mutually depend on each other through tests and libraries, this leads to cyclic dependencies that nix can't resolve. By exposing the components to nix as separate derivations this will only occur if you have mutually dependent components.

Build times

The Haskell builder in nixpkgs builds a package sequentially, first the library then the executables and finally the tests. It then executes the tests before the package is considered done. The upshot of this is that packages are only considered done if the test-suites passed. The downside is that if you have to compile multiple packages the likelihood of them failing is low, you have unnecessarily serialized your build. In a more aggressive setting libraries could start building as early as their dependent libraries are built. Of course they will have to be invalidated later should the test-suites of their dependencies fail, but this way we can make use of parallel building. In an ideal scenario this will reduce build times close to the optimum.

More logic in nix

The cabal2nix tool has a resolver that resolves system dependencies and licenses to values in nixpkgs. This logic ends up being a simple dictionary lookup and therefore can be a simple nix expression. This also offloads some of the work the cabal to nix translation tool needs to do into nix, and as such if changes are necessary (or needed to be performed ad hoc) there is no need to rebuild the conversion tool and subsequently mark every derived expression as out of date.

Decoupling

Finally, by treating Haskell.nix and nixpkgs as separate entities we can decouple the Haskell packages and infrastructure from the nixpkgs package set, and rely on it to provide us with system packages while staying up to date with Haskell packages from hackage while retaining a stable (or known to be good) nixpkgs revision.

Architecture

There are multiple components that play a part in the haskell.nix infrastructure. These are nix-tools, haskell.nix, hackage.nix, and stackage.nix.

                                             .-------------.     .-------------.
.- nix-tools ------.                         | haskell.nix |  .- | hackage.nix |
| .--------------. |   .----------------.    '-------------'  |  '-------------'
| | stack-to-nix |---> | stack-pkgs.nix |-.         |         |         |
| '--------------' |   '----------------' |         v         |         v
| .-------------.  |   .----------.       '--> .----------. <-'  .--------------.
| | plan-to-nix |----> | plan.nix |------.---> | pkgs.nix | <--- | stackage.nix |
| '-------------'  |   '----------'      |     '----------'      '--------------'
| .--------------. |   .--------------.  |          |
| | cabal-to-nix |---> | $package.nix |--'          v
| '--------------' |   '--------------'       .-------------.
'------------------'                          | default.nix |
                                              '-------------'
                                                    |
                                                    v
                                              .-------------.
                                              | release.nix |
                                              '-------------'

haskell.nix diagram

nix-tools

nix-tools is a Haskell package that provides the following tools:

  • cabal-to-nix: a .cabal to .nix transformer that retains conditional expressions.

  • stack-to-nix: a stack.yaml to .nix transformer that will read in a stack.yaml expression an generate a pkgs.nix file suited for use with haskell.nix.

  • plan-to-nix: a plan.json to .nix transformer that will read in a plan.json file and generate a pkgs.nix file suited for use with haskell.nix.

as well as a few other tools used to generate hackage.nix and stackage.nix.

haskell.nix

Haskell.nix is the runtime system for this Haskell infrastructure. It contains the component builder, as well as the system package and license mapping. Without haskell.nix the expressions generated by either of the nix-tools tools make little sense on their own.

hackage.nix

hackage.nix provides all cabal expressions from hackage as nix expressions. It is periodically updated to keep in sync with the set of packages available on hackage.

stackage.nix

stackage.nix is similar to hackage.nix but provides all stackage snapshots (lts, and nightly) as nix expressions. It naturally depends on hackage.nix to resolve package names, versions and revisions to the respective packages from hackage.nix.

Getting started

haskell.nix can automatically translate your Cabal or Stack project and its dependencies into Nix code.

Assuming you have Nix installed, you can start setting up your project.

Setting up the binary cache

IMPORTANT: you must do this or you will build several copies of GHC!

You can configure Nix to use our binary cache, which is pushed to by CI, so should contain the artifacts that you need.

You need to add the following sections to /etc/nix/nix.conf or, if you are a trusted user, ~/.config/nix/nix.conf (if you don't know what a "trusted user" is, you probably want to do the former). [...] denote any existing entries.

trusted-public-keys = [...] hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= [...]
substituters = [...] https://cache.iog.io [...]

If you're running NixOS, you need to add/update the following in your /etc/nixos/configuration.nix files instead.

# Binary Cache for Haskell.nix
nix.settings.trusted-public-keys = [
  "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
];
nix.settings.substituters = [
  "https://cache.iog.io"
];

NixOS-21.11 and older use slightly different settings.

# Binary Cache for Haskell.nix  
nix.binaryCachePublicKeys = [
  "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
];
nix.binaryCaches = [
  "https://cache.iog.io"
];   

This can be tricky to get setup properly. If you're still having trouble getting cache hits, consult the corresponding troubleshooting section.

Niv

Niv is a command line tool for keeping track of Nix project dependencies.

This guide assumes that the sources.haskellNix will be set to point a pinned copy of the haskell.nix github repo. One easy way to do this is to use Niv. If you prefer not to use Niv another option is described in the in the "Using haskell.nix without niv" section of this document.

If you want to use Nix Flakes to pin your dependencies then you should consider following the Getting started with flakes document instead of this one.

After installing niv you can initialize niv and pin the latest haskell.nix commit by running the following in the root directory of the project:

niv init
niv add input-output-hk/haskell.nix -n haskellNix

Then when you want to update to the latest version of haskellNix use:

niv update haskellNix

Scaffolding

The following work with stack.yaml and cabal.project based projects.

Add default.nix:

let
  # Read in the Niv sources
  sources = import ./nix/sources.nix {};
  # If ./nix/sources.nix file is not found run:
  #   niv init
  #   niv add input-output-hk/haskell.nix -n haskellNix

  # Fetch the haskell.nix commit we have pinned with Niv
  haskellNix = import sources.haskellNix {};
  # If haskellNix is not found run:
  #   niv add input-output-hk/haskell.nix -n haskellNix

  # Import nixpkgs and pass the haskell.nix provided nixpkgsArgs
  pkgs = import
    # haskell.nix provides access to the nixpkgs pins which are used by our CI,
    # hence you will be more likely to get cache hits when using these.
    # But you can also just use your own, e.g. '<nixpkgs>'.
    haskellNix.sources.nixpkgs-unstable
    # These arguments passed to nixpkgs, include some patches and also
    # the haskell.nix functionality itself as an overlay.
    haskellNix.nixpkgsArgs;
in pkgs.haskell-nix.project {
  # 'cleanGit' cleans a source directory based on the files known by git
  src = pkgs.haskell-nix.haskellLib.cleanGit {
    name = "haskell-nix-project";
    src = ./.;
  };
  # Specify the GHC version to use.
  compiler-nix-name = "ghc925"; # Not required for `stack.yaml` based projects.
}

Note: Git dependencies

If you have git dependencies in your project, you'll need to calculate sha256 hashes for them.

Working with a project

Top-level attributes are Haskell packages (incl. dependencies) part of your project.

To build the library component of a package in the project run:

nix-build -A your-package-name.components.library

There are also other components such as exes, tests, benchmarks and all. To build an executable:

nix-build -A your-package-name.components.exes.your-exe-name

To cross compile use the projectCross attribute:

nix-build -A projectCross.ghcjs.hsPkgs.your-package-name.components.exes.your-exe-name
nix-build -A projectCross.mingwW64.hsPkgs.your-package-name.components.exes.your-exe-name

To open a shell for use with cabal, hlint and haskell-language-server add shell.nix:

(import ./default.nix).shellFor {
  tools = {
    cabal = "latest";
    hlint = "latest";
    haskell-language-server = "latest";
  };
}

Then run:

nix-shell
cabal new-repl your-package-name:library:your-package-name
cabal new-build your-package-name

To open a shell for use with stack see the following issue.

Using haskell.nix without Niv

If you would prefer not to use niv you can replace sources = import ./nix/sources.nix {}; in the examples with:

let sources = {
    haskellNix = builtins.fetchTarball "https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz";
  };

The fetchTarball call above will always get the latest version, and is similar to an auto-updating Nix channel.

However, in your own project, you may wish to pin haskell.nix (as you would pin Nixpkgs). This will make your builds reproducible, more predictable, and faster (because the fixed version is cached).

Straightforward way of doing this is to change the branch name to a revision.

let sources = {
    haskellNix = builtins.fetchTarball "https://github.com/input-output-hk/haskell.nix/archive/f1a94a4c82a2ab999a67c3b84269da78d89f0075.tar.gz";
  };

There are other possible schemes for pinning. See Bumping Hackage and Stackage snapshots and Nix tutorial on reproducibility using pinning.

Going forward

Read through project function reference to see how the API works.

There are a number of things to explore further in the tutorials section.

Getting started with flakes

This version of the getting started guide is for users who are using Nix Flakes. The non flakes version of the guide is here.

haskell.nix can automatically translate your Cabal or Stack project and its dependencies into Nix code.

Assuming you have Nix installed, you can start setting up your project.

Using flake init and nix

The flake init command create an example hello package from hackage containing an flake.nix and nix/hix.nix file. The project can be used with regular nix tools.

nix flake init --template templates#haskell-nix --impure
# `--impure` is required by `builtins.currentSystem`
nix develop
cabal build

To view the contents of the flake run:

nix flake show

To build a component with nix:

nix build .#hello:exe:hello

To build and run a component:

nix run .#hello:exe:hello

Setting up the binary cache

IMPORTANT: you must do this or you will build several copies of GHC!

You can configure Nix to use our binary cache, which is pushed to by CI, so should contain the artifacts that you need.

You need to add the following sections to /etc/nix/nix.conf or, if you are a trusted user, ~/.config/nix/nix.conf (if you don't know what a "trusted user" is, you probably want to do the former).

trusted-public-keys = [...] hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= [...]
substituters = [...] https://cache.iog.io [...]

If you're running NixOS, you need to add/update the following in your /etc/nixos/configuration.nix files instead.

# Binary Cache for Haskell.nix
nix.settings.trusted-public-keys = [
  "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
];
nix.settings.substituters = [
  "https://cache.iog.io"
];

NixOS-21.11 and older use slightly different settings.

# Binary Cache for Haskell.nix  
nix.binaryCachePublicKeys = [
  "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
];
nix.binaryCaches = [
  "https://cache.iog.io"
];   

This can be tricky to get setup properly. If you're still having trouble getting cache hits, consult the corresponding troubleshooting section.

Scaffolding

The following work with stack.yaml and cabal.project based projects.

Add flake.nix:

{
  description = "A very basic flake";
  inputs.haskellNix.url = "github:input-output-hk/haskell.nix";
  inputs.nixpkgs.follows = "haskellNix/nixpkgs-unstable";
  inputs.flake-utils.url = "github:numtide/flake-utils";
  outputs = { self, nixpkgs, flake-utils, haskellNix }:
    flake-utils.lib.eachSystem [ "x86_64-linux" "x86_64-darwin" ] (system:
    let
      overlays = [ haskellNix.overlay
        (final: prev: {
          # This overlay adds our project to pkgs
          helloProject =
            final.haskell-nix.project' {
              src = ./.;
              compiler-nix-name = "ghc925";
              # This is used by `nix develop .` to open a shell for use with
              # `cabal`, `hlint` and `haskell-language-server`
              shell.tools = {
                cabal = {};
                hlint = {};
                haskell-language-server = {};
              };
              # Non-Haskell shell tools go here
              shell.buildInputs = with pkgs; [
                nixpkgs-fmt
              ];
              # This adds `js-unknown-ghcjs-cabal` to the shell.
              # shell.crossPlatforms = p: [p.ghcjs];
            };
        })
      ];
      pkgs = import nixpkgs { inherit system overlays; inherit (haskellNix) config; };
      flake = pkgs.helloProject.flake {
        # This adds support for `nix build .#js-unknown-ghcjs:hello:exe:hello`
        # crossPlatforms = p: [p.ghcjs];
      };
    in flake // {
      # Built by `nix build .`
      packages.default = flake.packages."hello:exe:hello";
    });
}

Note: Git dependencies

If you have git dependencies in your project, you'll need to calculate sha256 hashes for them.

Working with a project

Top-level attributes are Haskell packages (incl. dependencies) part of your project.

To build the library component of a package in the project run:

nix build .#your-package-name:lib:your-package-name

There are also other components such as exe, test and benchmark. To build an executable:

nix build .#your-package-name:exe:your-exe-name

To use the devShell provided by the flake run:

nix develop .
cabal repl your-package-name:lib:your-package-name
cabal build your-package-name

To open a shell for use with stack see the following issue.

Going forward

Read through project function reference to see how the API works.

There are a number of things to explore further in the tutorials section.

Getting started with Hix

Hix is a command line tool that provides an easy way to add haskell.nix support to existing haskell projects.

You will need nix installed and in you PATH with nix in PATH with experimental-features = [ "nix-command" "flakes" ]; configured. See https://nixos.wiki/wiki/Flakes for details.

Using hix init and nix

The hix init command adds a flake.nix and nix/hix.nix file. After that the project can be used with regular nix tools.

For instance to run cabal build on the hello package from hackage:

cabal unpack hello
cd hello-1.0.0.2
nix run "github:input-output-hk/haskell.nix#hix" -- init
nix develop
cabal build

To view the contents of the flake run:

nix flake show

To build a component with nix:

nix build .#hello:exe:hello

To build and run a component:

nix run .#hello:exe:hello

Installing Hix

To use the other Hix features first install Hix with:

nix-env -iA hix -f https://github.com/input-output-hk/haskell.nix/tarball/master

To update run to the latest version run:

hix update

Using hix develop, hix flake, hix build and hix run

These commands work the same as the nix versions without using the flake.nix. Instead a boiler plate haskell.nix flake.nix file is added to .hix-flake/flake.nix and used from there.

The is can be useful if the project already includes a flake.nix or if you do not intend to maintain one.

Then all of these should work without the need to run hix init:

hix develop
hix flake show
hix build .#hello:exe:hello
hix run .#hello:exe:hello

Using hix-shell and hix-build

These commands behave like nix-build and hix-shell would if a boiler plate default.nix and shell.nix we present.

hix-shell --run 'cabal build all'
hix-build -A hsPkgs.hello.components.exes.hello

Haskell.nix also provides reproducible development environments for your Haskell projects. These environments can contain not only GHC and your Haskell package dependencies, but also the required system libraries and build tools.

Inside the development shell, you can run commands such as ghc, ghci, or cabal new‑build (cabal build on Cabal 3.0), and they will have all dependencies available.

Every dependency will be cached in your Nix store. If you have set up Hydra CI, then your team can share pre-built dependencies.

These examples assume that you have created your package set as described in Creating Nix builds for your projects and it exists in a file called default.nix.

Note:

Old-style cabal build and stack builds are not (yet) supported. For example, stack will (by design) download and rebuild all dependencies, even though they are available in the shell. However, if you have a Stack project, you can generate the package set with Haskell.nix, then use cabal new‑build to work on it. Starting Cabal 3.0 cabal build will work out of the box, as new style builds are the default.

How to get a development shell

If you have a Cabal or Stack project with one or more packages (i.e. multiple .cabal files, not a single package with multiple components), then you will need a development environment that contains the dependencies of your packages, but not the packages themselves. This is what the shellFor function does.

# shell.nix
let
  project = import ./default.nix;
in
  project.shellFor {
    # ALL of these arguments are optional.

    # List of packages from the project you want to work on in
    # the shell (default is all the projects local packages).
    packages = ps: with ps; [
      pkga
      pkgb
    ];

    # Builds a Hoogle documentation index of all dependencies,
    # and provides a "hoogle" command to search the index.
    withHoogle = true;

    # Some common tools can be added with the `tools` argument
    tools = {
      cabal = "3.2.0.0";
      hlint = "latest"; # Selects the latest version in the hackage.nix snapshot
      haskell-language-server = "latest";
    };
    # See overlays/tools.nix for more details

    # Some you may need to get some other way.
    buildInputs = [ (import <nixpkgs> {}).git ];

    # Sellect cross compilers to include.
    crossPlatforms = ps: with ps; [
      ghcjs      # Adds support for `js-unknown-ghcjs-cabal build` in the shell
      # mingwW64 # Adds support for `x86_64-W64-mingw32-cabal build` in the shell
    ];

    # Prevents cabal from choosing alternate plans, so that
    # *all* dependencies are provided by Nix.
    exactDeps = true;
  }

See also: Haskell.nix Library Reference: shellFor

How to get a local Hoogle index

If you need a local Hoogle for all the dependencies of your project create this file

# shell-hoogle.nix
let
  project = import ./default.nix {};
in
  project.shellFor {
      packages = ps: [ps.my-package];
      withHoogle = true;
  }

and run nix-shell shell-hoogle.nix --run "hoogle server --local". This will open a local Hoogle server at http://127.0.0.1:8080.

How to get an ad-hoc development shell including certain packages

This creates a development environment with the given packages registered in the package database. The ghcWithPackages function operates on a Haskell.nix package set, and accepts an argument that selects packages from the larger package set.

# shell.nix
let
  haskellNix = import (builtins.fetchTarball "https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz") {};
  nixpkgs = import haskellNix.sources.nixpkgs haskellNix.nixpkgsArgs;
  haskell = nixpkgs.haskell-nix;
in
  haskell.haskellPackages.ghcWithPackages (ps: with ps;
    [ lens conduit conduit-extra ])

If you need a Hoogle documentation index, use ghcWithHoogle in place of ghcWithPackages.

How to get packages from a certain Stackage snapshot

Haskell.nix knows about every released Stackage snapshot. You can use it to build packages from a given snapshot, without setting up a full project.

let
  haskellNix = import (builtins.fetchTarball "https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz") {};
  nixpkgs = import haskellNix.sources.nixpkgs haskellNix.nixpkgsArgs;
  haskell = nixpkgs.haskell-nix;
in
  haskell.snapshots."lts-13.18".alex.components.exes.alex

There are Haskell.nix package sets for every Stackage snaphot under haskell.snapshots.

The alias haskell.haskellPackages corresponds to the package set for a recent LTS Haskell version.

You can use ghcWithPackages on any of these package sets to quickly get a shell with some packages.

⚠️ Warning:

The build will not work if your Nixpkgs does not contain the version of GHC specified in the snapshot. Nixpkgs only carries the latest version of each recent release series, so many snapshots can't be built.

Emacs IDE support

Once you have a development shell, then you can begin configuring Emacs to use it. The way I do it is:

  1. Run lorri watch to continuously build the shell environment and maintain GC roots.

  2. Use emacs‑direnv to push the development environment into Emacs.

  3. Use Dante for highlighting errors and auto-completion. You must customize Dante to prevent it from automatically using nix‑shell or stack. Trim dante‑methods to just new‑build and bare‑ghci.

    You can also use .dir‑locals.el for this. If your project has multiple targets, set dante‑target per-directory.

  4. For haskell‑mode interactive Haskell, set haskell‑process‑type to cabal‑new‑repl.

Using nix repl

It's sometimes useful to load Haskell.nix in the REPL to explore attrsets and try examples.

# example.nix
{ nixpkgs ? <nixpkgs> }:
rec {
  haskell = import nixpkgs (import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {}).nixpkgsArgs;
  pkgNames = haskell.pkgs.lib.attrNames haskell.haskell-nix.snapshots."lts-13.18";
}

Load the example file:

$ nix repl
Welcome to Nix 2.10.3. Type :? for help.

nix-repl> :l <nixpkgs>
Added 16938 variables.

nix-repl> :l example.nix
Added 2 variables.

nix-repl> lib.take 5 pkgNames
[ "AC-Angle" "ALUT" "ANum" "Agda" "Allure" ]

nix-repl> :q

Now that you have nix-tools and are able to import Haskell.nix, you can continue to the next chapter.

cleanGit

To filter out just the files in your git index use haskell-nix.haskellLib.cleanGit { src = ./.; } where ./. is the root of your git repo (or a git work tree).

First it filters just the files needed to run git index, then it uses the results of that to filter your directory. It does not need to parse the .gitignore files at all, but we do need to git add our files before they will be included. cleanGit source.

In addition haskell.nix (including cleanGit) uses a version of cleanSourceWith with a subdir argument to filter out just the package it is building. Then it uses the info from the cabal file to filter just the source dirs for the component it is building. That way if we modify a test in a package nix will not rebuild the library in that package (or anything that depends on that package's library).

There is a downside to this though. If we have a test that depends on something outside the scope of what is described in its entry in the in the .cabal file it will not see it. For instance perhaps it needs to run hlint or doctest on the library source. There are ways to fix this with a module:

Use extraSrcFiles to add dirs the test needs (this will not result in a change to the .cabal file the test will still be built the same).

components.tests.test.extraSrcFiles = [ "subdir-needed-by-test" ];

Or alternatively, override the source with a suitable filter function.

components.tests.test.src = haskell-nix.haskellLib.cleanSourceWith {
    inherit src;
    subdir = "path-to-package";
    filter = ...
};

Multiple Git Repositories with cleanGits

Some times it is handy to temporarily use a relative path between git repos. If the repos are individually cleaned this is not possible (since the cleaned version of one repo will never include the files of the other).

There are 3 options:

  • We could symlinkJoin the cleaned directories together, but the result could not be cleaned and any change would to either repo would result in a rebuild of everything.

  • We could add one repo to the other as a submodule, but adding and then removing a submodule is a pain and it does not work well if you have more than one repo that needs to share the submodule.

  • We could add a source-repository-package but then we would have to commit each change before testing.

cleanGits allows us to specify a root directory and any number of sub directories containing git repos.

For example if repoA and repoB are two git repos with cabal packages and want to use the repoB package when building repoA. First we can add ../repoB to repoA/cabal.project:

packages:
  ./.
  ../repoB

Then in repoA/default.nix we can use:

haskell-nix.project {
  src = haskell-nix.haskellLib.cleanSourceWith {
    src = haskell-nix.haskellLib.cleanGits {
      name = "root";
      src = ../.;    # Parent dir that contains repoA and repoB
      gitDirs = [ "repoA" "repoB" ];
    };
    subDir = "repoA";       # Where to look for the `cabal.project`
    includeSiblings = true; # Tells it not to exclude `repoB` dir
  };
}

Handling git repositories in projects

Both stack.yaml and cabal.project files can contain references to git repositories containing the version of a particular package that we wish to use. This is mostly handled automatically by nix-tools and haskell.nix however when we want to use a nix system that is configured to use restricted mode (typically hydra) it will need additional hashes for the referenced repositories.

When using project, cabalProject or stackProject functions you can include the hash needed in a comment.

To calculate the hash use nix-prefetch-git:

$ nix-prefetch-git https://github.com/input-output-hk/haskell.nix.git bc01ebc05a8105035c9449943046b46c8364b932
...
{
  "url": "https://github.com/input-output-hk/haskell.nix.git",
  "rev": "bc01ebc05a8105035c9449943046b46c8364b932",
  "date": "2019-05-30T13:13:18+08:00",
  "sha256": "003lm3pm024vhbfmii7xcdd9v2rczpflxf7gdl2pyxia7p014i8z",
  "fetchSubmodules": false
}

Cabal.project

Add a --sha256 comment to the cabal.project file:

source-repository-package
  type: git
  location: https://github.com/input-output-hk/haskell.nix.git
  tag: bc01ebc05a8105035c9449943046b46c8364b932
  subdir: test/cabal-simple
  --sha256: 003lm3pm024vhbfmii7xcdd9v2rczpflxf7gdl2pyxia7p014i8z

Stack

Add a # nix-sha256 comment to the stack.yaml file:

extra-deps:
- git: https://github.com/input-output-hk/haskell.nix.git
  commit: bc01ebc05a8105035c9449943046b46c8364b932
  subdirs:
    - test/cabal-simple
  # nix-sha256: 003lm3pm024vhbfmii7xcdd9v2rczpflxf7gdl2pyxia7p014i8z

Avoiding modifying cabal.project and stack.yaml

In some cases we cannot modify the cabal.project or stack.yaml file to add sha256 comments. As an alternative we can pass in a sha256map. For instance, pandoc includes a cabal.project file on hackage which includes a source-repository-package stanza for pandoc-citeproc:

{ haskell-nix, testSrc } :
let
  pandoc = haskell-nix.hackage-package {
    name         = "pandoc";
    version      = "2.9.2.1";
    index-state  = "2020-04-15T00:00:00Z"; 
    # Function that returns a sha256 string by looking up the location
    # and tag in a nested attrset
    sha256map =
      { "https://github.com/jgm/pandoc-citeproc"."0.17"
          = "0dxx8cp2xndpw3jwiawch2dkrkp15mil7pyx7dvd810pwc22pm2q"; };
  };
in
  pandoc.components.exes.pandoc

Mapping non-Haskell dependencies to Nixpkgs

Cabal files may contain dependencies to external non-Haskell dependencies via:

If there is a pkgs attribute in Nixpkgs that matches the name given in the Cabal file, then it will be added as a dependency (see the output of cabal-to-nix). Otherwise, there needs to be a mapping from Cabal file names (decided by the package author) to Nix package identifiers.

Nixpkgs overlay

The user may solve it by themself by overriding Nixpkgs and adding a package alias. For example:

nixpkgs.overlays = [
  (self: super: {
    icuuc = self.icu;
    icui18n = self.icu;
    icudata = self.icu;
  })
];

The user can map package(s) in Nixpkgs to a pkgconfig-depends name by overlaying the haskell-nix.extraPkgconfigMappings attribute:

nixpkgs.overlays = [
  (self: super: {
    haskell-nix = super.haskell-nix // {
      extraPkgconfigMappings = super.haskell-nix.extraPkgconfigMappings // {
          # String pkgconfig-depends names are mapped to lists of Nixpkgs
          # package names
          "SDL_gpu" = [ "SDL_gpu" ];
      };
    };
  })
];

Replace libraries of components

If a component is missing a dependency it can be added via modules. For example:

project = pkgs.haskell-nix.project' {
  src = self;
  compiler-nix-name = "ghc8102";
  modules = [{
    # Replace `extra-libraries` dependencies
    packages.X11.components.library.libs = pkgs.lib.mkForce (with pkgs.xorg;
        [ libX11 libXrandr libXext libXScrnSaver libXinerama ]);
  }];
};

Mapping in Haskell.nix

Alternatively, if the name is commonly used, an alias can be added to the Haskell.nix sources, so that it's solved for all users.

  • lib/pkgconf-nixpkgs-map.nix — for pkgconfig-depends.

    Each mapping entry is a list of packages.

  • lib/system-nixpkgs-map.nix — for build-tool-depends, frameworks, extra-libraries, etc.

    Each name can be mapped to:

    1. A single package from nixpkgs.
    2. null — eliminates the dependency
    3. A list of packages — sometimes needed for dependencies such as X11.

Tip: Open a PR

Please go ahead and open a pull request to improve the package mappings.

Bumping Hackage and Stackage snapshots

haskell.nix relies on some generated data providing information about packages in Hackage and Stackage snapshots. These are kept in hackage.nix and stackage.nix respectively. If your project depends on a Hackage package, then the hackage.nix revision used must be new enough to contain that, and likewise for Stackage snaphots and stackage.nix.

Updating and pinning hackage.nix and stackage.nix

haskell.nix pins particular revisions of these repositories internally, both for our own usage in testing, and so that users have a sensible default when getting started. These revisions are updated nightly, so you can get newer revisions of hackage.nix and stackage.nix by updating your revision of haskell.nix itself.

However, this exposes you to changes in haskell.nix which you may not want, such as changes that force compiler rebuilds, or the occasional bug. Instead, you can pin hackage.nix and stackage.nix independently. For example:

let
  # You can use a tool like `niv` to manage this boilerplate
  hackageSrc = builtins.fetchTarball "https://github.com/input-output-hk/hackage.nix/archive/master.tar.gz";
  stackageSrc = builtins.fetchTarball "https://github.com/input-output-hk/stackage.nix/archive/master.tar.gz";
  haskellSrc = builtins.fetchTarball "https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz";

  haskellNix = import haskellSrc {
    # This allows you to override the pins used by `haskell.nix` internally
    sourcesOverride = {
      hackage = hackageSrc;
      stackage = stackageSrc;
    };
  };
in {
  inherit haskellNix
  # ...
}

This way you can change the revisions of hackage.nix and stackage.nix without changing haskell.nix.

However, bear in mind that Stackage refers to Hackage, so your Stackage pin should never be newer than your Hackage pin.

Materialization

What is materialization?

Capturing and storing the Nix files for a project so that they do not need to be built (or checked). This allows us to cache the input of an IFD (import from derivation).

Why use materialization?

Using functions like project, cabalProject, stackProject and hackage-package results in a lot of dependencies (all the dependencies of nix-tools for instance).

  • They can be slow to calculate (even if no work needs to be done it is not unusual for it to take 5 seconds per project).

  • They can be slow to build (or download) on machines that do not yet have them in the Nix store.

  • Hydra does not show progress because it does not provide feedback until it has a list of jobs and the list of jobs cannot depend on the Nix expressions being present (although this is often blamed on IFD it would be the same if it wrote out JSON files and read them in)

When is it OK to materialize?

  • The Nix expressions are unlikely to change frequently (and when it does you are happy to manually update it).

  • You are happy to script something to update the materialized Nix files automatically.

  • You are certain that the IFD you materialize is not system-dependent. If it was you'd obtain different Nix expressions depending on which system the IFD was evaluated.

How can we materialize the Nix files?

Lets say we want to build hlint. We might start with an hlint.nix file that looks like this:

let inherit (import ./. {}) sources nixpkgsArgs;
    pkgs = import sources.nixpkgs nixpkgsArgs;
    hlint = pkgs.haskell-nix.hackage-package {
      compiler-nix-name = "ghc8102";
      name = "hlint";
      version = "2.2.11";
    };
in hlint

Building this may result in a lot of output, but if you build it again it should give just:

$ nix-build hlint.nix -A components.exes.hlint
trace: No index state specified for hlint, using the latest index state that we know about (2021-01-04T00:00:00Z)!
/nix/store/2ybrfmcp79gg75ad4pr1cbxjak70yg8b-hlint-exe-hlint-2.2.11

To materialize the Nix files we need to take care to pin down the inputs. Stack projects have their inputs pinned through specifying the snapshot. For cabal projects this means we must specify the index-state of hackage we want to use:

let inherit (import ./. {}) sources nixpkgsArgs;
    pkgs = import sources.nixpkgs nixpkgsArgs;
    hlint = pkgs.haskell-nix.hackage-package {
      compiler-nix-name = "ghc8102";
      name = "hlint";
      version = "2.2.11";
      index-state = "2021-01-04T00:00:00Z";
    };
in hlint

Now if we build again we get a hint telling use how to calculate a suitable sha256 hash to turn the derivation containing the Nix files into a fixed-output derivation:

$ nix-build hlint.nix -A components.exes.hlint
trace: To make project.plan-nix for hlint a fixed-output derivation but not materialized, set `plan-sha256` to the output of the 'calculateMaterializedSha' script in 'passthru'.
trace: To materialize project.plan-nix for hlint entirely, pass a writable path as the `materialized` argument and run the 'updateMaterialized' script in 'passthru'.
/nix/store/2ybrfmcp79gg75ad4pr1cbxjak70yg8b-hlint-exe-hlint-2.2.11

$ nix-build hlint.nix -A project.plan-nix.passthru.calculateMaterializedSha | bash
trace: To make project.plan-nix for hlint a fixed-output derivation but not materialized, set `plan-sha256` to the output of the 'calculateMaterializedSha' script in 'passthru'.
trace: To materialize project.plan-nix for hlint entirely, pass a writable path as the `materialized` argument and run the 'updateMaterialized' script in 'passthru'.
04hdgqwpaswmyb0ili7fwi6czzihd6x0jlvivw52d1i7wv4gaqy7

For a Stack project all occurences of plan-nix and plan-sha256 are replaced by stack-nix and stack-sha256, respectively. We can add the hash as plan-sha256:

let inherit (import ./. {}) sources nixpkgsArgs;
    pkgs = import sources.nixpkgs nixpkgsArgs;
    hlint = pkgs.haskell-nix.hackage-package {
      compiler-nix-name = "ghc8102";
      name = "hlint";
      version = "2.2.11";
      index-state = "2021-01-04T00:00:00Z";
      plan-sha256 = "04hdgqwpaswmyb0ili7fwi6czzihd6x0jlvivw52d1i7wv4gaqy7";
    };
in hlint

Just adding the hash might help reuse of the cached Nix expressions, but Nix will still calculate all the dependencies (which can add seconds to nix-build and nix-shell commands when no other work is needed) and users who do not yet have the dependencies in their store will have to wait while they are built or downloaded.

Running nix-build again gives us a hint on what we can do next:

$ nix-build hlint.nix -A components.exes.hlint
trace: To materialize project.plan-nix for hlint entirely, pass a writable path as the `materialized` argument and run the 'updateMaterialized' script in 'passthru'.
/nix/store/2ybrfmcp79gg75ad4pr1cbxjak70yg8b-hlint-exe-hlint-2.2.11

To capture the Nix expressions we can do something like:

let inherit (import ./. {}) sources nixpkgsArgs;
    pkgs = import sources.nixpkgs nixpkgsArgs;
    hlint = pkgs.haskell-nix.hackage-package {
      compiler-nix-name = "ghc8102";
      name = "hlint";
      version = "2.2.11";
      index-state = "2021-01-04T00:00:00Z";
      plan-sha256 = "04hdgqwpaswmyb0ili7fwi6czzihd6x0jlvivw52d1i7wv4gaqy7";
      materialized = ./hlint.materialized;
    };
in hlint

Now we can copy the Nix files needed and build with:

$ nix-build hlint.nix 2>&1 | grep -om1 '/nix/store/.*-updateMaterialized' | bash
$ nix-build hlint.nix -A components.exes.hlint
building '/nix/store/wpxsgzl1z4jnhfqzmzg3xxv3ljpmzr5h-hlint-plan-to-nix-pkgs.drv'...
/nix/store/2ybrfmcp79gg75ad4pr1cbxjak70yg8b-hlint-exe-hlint-2.2.11

How can we check sha256 and materialized are up to date?

Let's pretend we had to go back to hlint version 2.2.10. We can tell haskell.nix to check the materialization either by:

  • Removing the materialization files with rm -rf hlint.materialized

  • Temporarily adding checkMaterialization = true;

If we choose to add the checkMaterialization flag you would have:

let inherit (import ./. {}) sources nixpkgsArgs;
    pkgs = import sources.nixpkgs nixpkgsArgs;
    hlint = pkgs.haskell-nix.hackage-package {
      compiler-nix-name = "ghc8102";
      name = "hlint";
      version = "2.2.10";
      index-state = "2021-01-04T00:00:00Z";
      plan-sha256 = "04hdgqwpaswmyb0ili7fwi6czzihd6x0jlvivw52d1i7wv4gaqy7";
      materialized = ./hlint.materialized;
      checkMaterialization = true;
    };
in hlint

This will fail and report the details of what is wrong and how to fix it:

$ nix-build hlint.nix -A components.exes.hlint

...

Calculated hash for hlint-plan-to-nix-pkgs was not 04hdgqwpaswmyb0ili7fwi6czzihd6x0jlvivw52d1i7wv4gaqy7. New hash is :
    plan-sha256 = "0jsgdmii0a6b35sd42cpbc83s4sp4fbx8slphzvamq8n9x49i5b6";
Materialized nix used for hlint-plan-to-nix-pkgs incorrect. To fix run: /nix/store/6wp0zzal40ls874f5ddpaac7qmii9y4z-updateMaterialized
builder for '/nix/store/61a0vginv76w4p9ycyd628pjanav06pl-hlint-plan-to-nix-pkgs.drv' failed with exit code 1
error: build of '/nix/store/61a0vginv76w4p9ycyd628pjanav06pl-hlint-plan-to-nix-pkgs.drv' failed
(use '--show-trace' to show detailed location information)

Checking the materialization requires Nix to do all the work that materialization avoids. So while it might be tempting to leave checkMaterialization = true all the time, we would be better off just removing materialized and plan-sha256.

How can we update the Nix files with a script?

We can simply put the commands we used earlier in a script:

#!/bin/sh

# Output new plan-sha256
nix-build hlint.nix -A project.plan-nix.passthru.calculateMaterializedSha | bash

# Update materialized Nix expressions
nix-build hlint.nix 2>&1 | grep -om1 '/nix/store/.*-updateMaterialized' | bash

Can we skip making a copy and use materialized = /nix/store/...?

Yes and it gives us the same speed improvement, however:

  • It does not help at all in restricted-eval mode (Hydra).

  • Users will still wind up building or downloading the dependencies needed to build the Nix files (if they do not have them).

For those reasons it might be best to make a copy instead of using the /nix/store/... path directly.

If you really want to use the /nix/store/... path directly you should guard against the path not existing as passing in a non-existing path is now an error:

let inherit (import ./. {}) sources nixpkgsArgs;
    pkgs = import sources.nixpkgs nixpkgsArgs;
    hlintPlan = /nix/store/63k3f8bvsnag7v36vb3149208jyx61rk-hlint-plan-to-nix-pkgs;
    hlint = pkgs.haskell-nix.hackage-package {
      compiler-nix-name = "ghc8102";
      name = "hlint";
      version = "2.2.11";
      index-state = "2021-01-04T00:00:00Z";
      plan-sha256 = "04hdgqwpaswmyb0ili7fwi6czzihd6x0jlvivw52d1i7wv4gaqy7";
      materialized = if __pathExists hlintPlan then hlintPlan else null;
    };
in hlint

Running when no building is needed is still slow in restricted evaluation mode.

$ time nix-build --option restrict-eval true -I . --option allowed-uris "https://github.com/NixOS https://github.com/input-output-hk" hlint.nix -A components.exes.hlint --show-trace
/nix/store/2ybrfmcp79gg75ad4pr1cbxjak70yg8b-hlint-exe-hlint-2.2.11

real	0m4.463s
user	0m4.440s
sys	0m0.461s
$ time nix-build hlint.nix -A components.exes.hlint
/nix/store/2ybrfmcp79gg75ad4pr1cbxjak70yg8b-hlint-exe-hlint-2.2.11

real	0m2.206s
user	0m1.665s
sys	0m0.332s

Cross compilation

Cross compilation of Haskell projects involves building a version of GHC that outputs code for the target platform, and providing builds of all library dependencies for that platform.

First, understand how to cross-compile a normal package from Nixpkgs. Matthew Bauer's Beginners' guide to cross compilation in Nixpkgs is a useful resource.

Using an example from the guide, this builds GNU Hello for a Raspberry Pi:

nix build -f '<nixpkgs>' pkgsCross.raspberryPi.hello

We will use the same principle in Haskell.nix — replacing the normal package set pkgs with a cross-compiling package set pkgsCross.raspberryPi.

Raspberry Pi example

This is an example of using Haskell.nix to build the Bench command-line utility, which is a Haskell program.

{ pkgs ? import <nixpkgs> {} }:
let
  haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz);
  native = haskellNix { inherit pkgs; };
in
  native.haskellPackages.bench.components.exes.bench

Now switch the package set as in the previous example:

{ pkgs ? import <nixpkgs> {} }:
let
  haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz);
  raspberryPi = haskellNix { pkgs = pkgs.pkgsCross.raspberryPi; };
in
  raspberryPi.haskellPackages.bench.components.exes.bench

You should be prepared for a long wait because it first needs to build GHC, before building all the Haskell dependencies of Bench. If all of these dependencies compiled successfully, I would be very surprised!

Hint:

The above example won't build, but you can try and see, if you like. It will fail on clock-0.7.2, which needs a patch to build.

To fix the build problems, you must add extra configuration to the package set. Your project will have a mkStackPkgSet or mkCabalProjectPkgSet. It is there where you must add module options for setting compiler flags, adding patches, and so on.

Note:

Note that haskell.nix will automatically use qemu to emulate the target when necessary to run Template Haskell splices.

Static executables with Musl libc

Another application of cross-compiling is to produce fully static binaries for Linux. For information about how to do that with the Nixpkgs Haskell infrastructure (not Haskell.nix), see nh2/static‑haskell‑nix. Vaibhav Sagar's linked blog post is also very informative.

{ pkgs ? import <nixpkgs> {} }:
let
  haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz);
  musl64 = haskellNix { pkgs = pkgs.pkgsCross.musl64; };
in
  musl64.haskellPackages.bench.components.exes.bench

This example will build Bench linked against Musl libc. However the executable will still be dynamically linked. To get fully static executables you must add package overrides to:

  1. Disable dynamic linking
  2. Provide static versions of system libraries. (For more details, see Vaibhav's article).
{
  packages.bench.components.exes.bench.configureFlags =
    lib.optionals stdenv.hostPlatform.isMusl [
      "--disable-executable-dynamic"
      "--disable-shared"
      "--ghc-option=-optl=-pthread"
      "--ghc-option=-optl=-static"
      "--ghc-option=-optl=-L${gmp6.override { withStatic = true; }}/lib"
      "--ghc-option=-optl=-L${zlib.static}/lib"
    ];
}

Note: Licensing

Note that if copyleft licensing your program is a problem for you, then you need to statically link with integer-simple rather than integer-gmp. However, at present, Haskell.nix does not provide an option for this.

How to cross-compile your project

Set up your project Haskell package set.

# default.nix
{ pkgs ? import <nixpkgs> {}}:
let
  # Import the Haskell.nix library,
  haskell = import (builtins.fetchTarball "https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz") {
    inherit pkgs;
  };

  # Instantiate a package set using the generated file.
  pkgSet = haskell.mkCabalProjectPkgSet {
    plan-pkgs = import ./pkgs.nix;
    pkg-def-extras = [];
    modules = [
      {
        # You will need to put build fixes here.
      }
    ];
  };
in
  pkgSet.config.hsPkgs

Apply that package set to the Nixpkgs cross package sets that you are interested in.

We are going to expand the pkgs.pkgsCross shortcut to be more explicit.

let
  pkgs = import <nixpkgs> {}
in {
  shortcut = pkgs.pkgsCross.SYSTEM;
  actual = import <nixpkgs> { crossSystem = pkgs.lib.systems.examples.SYSTEM; };
}

In the above example, for any SYSTEM, shortcut and actual are the same package set.

# release.nix
let
  myProject = import ./default.nix;

  pkgsNative = import <nixpkgs> {};
  pkgsRaspberryPi = import <nixpkgs> {
    crossSystem = pkgsNative.lib.systems.examples.raspberryPi;
  };

  native = myProject { pkgs = pkgsNative; };
  crossRaspberryPi = myProject { pkgs = pkgsRaspberryPi; };

in {
  my-project-native = native.my-project.components.exes.my-project;
  my-project-raspberry-pi = crossRaspberryPi.my-project.components.exes.my-project;
}

Try to build it, and apply fixes to the modules list, until there are no errors left.

Coverage

haskell.nix can generate coverage information for your package or project using Cabal's inbuilt hpc support.

Prerequisites

To get a sensible coverage report, you need to enable coverage on each of the packages of your project:

pkgs.haskell-nix.project {
  src = pkgs.haskell-nix.haskellLib.cleanGit {
    name = "haskell-nix-project";
    src = ./.;
  };
  compiler-nix-name = "ghc884";

  modules = [{
    packages.$pkg.components.library.doCoverage = true;
  }];
}

If you would like to make coverage optional, add an argument to your nix expression:

{ withCoverage ? false }:

pkgs.haskell-nix.project {
  src = pkgs.haskell-nix.haskellLib.cleanGit {
    name = "haskell-nix-project";
    src = ./.;
  };
  compiler-nix-name = "ghc884";

  modules = pkgs.lib.optional withCoverage [{
    packages.$pkg.components.library.doCoverage = true;
  }];
}

Per-package

nix-build default.nix -A "projectWithCoverage.$pkg.coverageReport"

This will generate a coverage report for the package you requested. All tests that are enabled (configured with doCheck == true) are included in the coverage report.

See the developer coverage docs for more information.

Project-wide

nix-build default.nix -A "projectWithCoverage.projectCoverageReport"

This will generate a coverage report for all the local packages in your project.

See the developer coverage docs for more information.

Custom

By default, the behaviour of the coverageReport attribute is to generate a coverage report that describes how that package affects the coverage of all local packages (including itself) in the project.

The default behaviour of projectCoverageReport is to sum the default coverage reports (produced by the above process) of all local packages in the project.

You can modify this behaviour by using the coverageReport and projectCoverageReport functions found in the haskell.nix library:

# default.nix
{ pkgs ? import <nixpkgs> {}}:
let
  inherit (pkgs.haskell-nix) haskellLib;

  project = haskellLib.project {
    src = pkgs.haskell-nix.haskellLib.cleanGit {
      name = "haskell-nix-project";
      src = ./.;
    };
    compiler-nix-name = "ghc884";

    modules = [{
      packages.$pkgA.components.library.doCoverage = true;
      packages.$pkgB.components.library.doCoverage = true;
    }];
  };

  # Generate a coverage report for $pkgA that only includes the
  # unit-test check and only shows coverage information for $pkgA, not
  # $pkgB.
  custom$pkgACoverageReport = haskellLib.coverageReport rec {
    name = "$pkgA-unit-tests-only"
    inherit (project.$pkgA.components) library;
    checks = [project.$pkgA.components.checks.unit-test];
    # Note that this is the default value of the "mixLibraries"
    # argument and so this line isn't really necessary.
    mixLibraries = [project.$pkgA.components.library];
  };

  custom$pkgBCoverageReport = haskellLib.coverageReport rec {
    name = "$pkgB-unit-tests-only"
    inherit (project.$pkgB.components) library;
    checks = [project.$pkgB.components.checks.unit-test];
    mixLibraries = [project.$pkgB.components.library];
  };
 
  # Generate a project coverage report that only includes the unit
  # tests of the project, and only shows how each unit test effects
  # the coverage of it's package, and not other packages in the
  # project.
  allUnitTestsProjectReport = haskellLib.projectCoverageReport [custom$pkgACoverageReport custom$pkgBCoverageReport];
in {
  inherit project custom$pkgACoverageReport custom$pkgBCoverageReport allUnitTestsProjectCoverageReport;
}

Build a specific package from Hackage or Stackage

From a Stackage snapshot

To build a package, say lens, from a Stackage snapshot, say lts-13.28, you could run:

nix-build -E '(with import <nixpkgs> (import (builtins.fetchTarball "https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz") {}).nixpkgsArgs; haskell-nix.snapshots."lts-13.28").lens.components.library'

This would build the (public) library component of the lens package as fixed by the lts-13.28 stackage snapshot. Nightly snapshots like nightly-2020-06-21 are also available.

A specific version from Hackage

To build any package from hackage, say lens, at any version, say 4.17.1, you could run:

nix-build -E '(with import <nixpkgs> (import (builtins.fetchTarball "https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz") {}).nixpkgsArgs; (haskell-nix.hackage-package { name = "lens"; version = "4.17.1"; compiler-nix-name = "ghc8102"; })).components.library'

This would build the (public) library component of the lens-4.17.1 package from hackage.

Pinning hackage index

The dependencies would be resolved against the most recent hackage-index-state which comes with your haskell.nix checkout via the hackage.nix pin. A specific one can be specified as well:

nix-build -E '(with import <nixpkgs> (import (builtins.fetchTarball "https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz") {}).nixpkgsArgs; (haskell-nix.hackage-package { name = "lens"; version = "4.17.1"; compiler-nix-name = "ghc8102"; index-state = "2019-07-14T00:00:00Z"; })).components.library'

This would use the hackage index as of 2019-07-14T00:00:00Z to produce a build plan for the lens-4.17.1 package.

Content addressed derivations

Introduction

Floating content addressed derivations (from now CA derivations) is an experimental feature which substantially change how the hashes in the store paths are calculated. Indeed, normally derivations are input addressed i.e. the outputs store paths depends only on the derivation inputs, instead with CA derivations they depend on the content of the outputs.

This has two main advantages:

  • The so-called "early cutoff", namely the ability of Nix to stop a build if the build outputs would be something already built. For example suppose you add a comment in an Haskell source, at this point Nix will rebuild the component depending on this source but since the output will be the same (adding a comment is an "output-invariant" change for ghc) every other component that depends on that will not be rebuilt.
  • Users of the same Nix store does not need to trust each other when using substituters.

You can find more information in the ca-derivations page on the wiki (and in the other resources linked there).

Usage

Enable CA derivations in your system

First of all your Nix installation must support the ca-derivations experimental feature, this can done by adding the following in your nix.conf:

experimental-features = ca-derivations

Or if you use NixOS:

nix.extraOptions = ''
    experimental-features = ca-derivations
'';

Enable CA derivations in your project

At this point you can pass a new module to project' that tells haskell.nix to build every component in the project as CA derivation.

haskell-nix.project' {
	# ...
	
	modules = [{
		contentAddressed = true;
		# packages.project-name.components.exes.executable.contentAddressed = true;
	}];
};

Optionally you can also specify which components you don't want to be content addressed.

Known problems

Limitation of the current CA derivations implementation

As explained in the RFC 62

The current implementation has a naive approach that just forbids fetching a path if the local system has a different realisation for the same drv output. This approach is simple and correct, but it's possible that it might not be good-enough in practice as it can result in a totally useless binary cache in some pathological cases.

For example, suppose that your machine builds a derivation A producing an output A.out in your store and that after that a CI machine builds the same derivation A but producing a different output A.out' and populating a cache with this output. At this point, if you need to build a derivation B that depends on A, since you already have the realisation A.out in your local store and you can't get B.out from the cache and you will end up building B even if one of its realisation is in the cache.

This means that, in some cases, enabling CA derivations would lead to more rebuilds than not having it.

Hydra

Hydra currently doesn't support CA derivations, efforts are being made in this direction.

GHC is not deterministic

Currently ghc is determinstic only disabling the parallel building i.e. passing -j1. Here the upstream issue.

Having a deterministic ghc would be a dream since it will automatically fix all the pathological cases about substituters discussed above and would allow haskell.nix to parallel build even when using CA derivations.

Supported GHC Versions

The following GHC versions are defined in haskell.nix (there is a derivation for each, though not all are cached or tested by CI):

  • 8.4.4
  • 8.6.{1,2,3,4,5}
  • 8.8.{1,2,3,4}
  • 8.10.{1,2,3,4,5}
  • 9.0.1
  • 9.2.1
  • 9.2.2

The following table shows the Nixpkgs/GHC versions which are built/cached, and which of those are further tested. If you use a combination of Nixpkgs version and GHC version which is in this table, you should hit our cache, saving considering time by not building GHC and a few additional tools.

Note that if you try to use haskell.nix as an overlay over Nixpkgs from a standard Nixpkgs channel you will likely get a cache miss. To hit our cache you really should use an instance of Nixpkgs provided by haskell.nix itself.

Nixpkgs versionNixpkgs pinningGHC versioncompiler-nix-nameTested in CI?
22.05nixpkgs-22058.6.5ghc865No
22.05nixpkgs-22058.10.7ghc8107No
unstablenixpkgs-unstable8.6.5ghc865No
unstablenixpkgs-unstable8.8.4ghc884No
unstablenixpkgs-unstable8.10.7ghc8107Yes
unstablenixpkgs-unstable9.0.2ghc902No
unstablenixpkgs-unstable9.2.4ghc924Yes

See ci.nix for the source of truth about what is built and tested (in the off chance this document is out-of-sync with your checkout).

See the getting started guide for instructions on how to set up Nix to take advantage of our cache when building. This guide also covers where to use the Nixpkgs pinning and compiler-nix-name settings from the table above. For further information, see the instructions for how to pin Nixpkgs.

See overlays/bootstrap.nix for a full list of all the valid compiler-nix-names beyond what's cached/tested in CI. You're free to use these, but be ready for longer build times.

Lastly, see instructions on adding new GHC versions in the event that what's in haskell.nix doesn't suit your needs.

Command line tools

To install the command line tools refer to the Installing nix-tools section.

stack-to-nix

stack-to-nix - a stack to nix converter

Usage: stack-to-nix (-o|--output DIR) [--stack-yaml FILE]
                    [--ignore-package-yaml] [--cache FILE]
  Generate a Nix expression for a Haskell package using Stack

Available options:
  -o,--output DIR          Generate output in DIR
  --stack-yaml FILE        Override project stack.yaml (default: "stack.yaml")
  --ignore-package-yaml    disable hpack run and use only cabal disregarding
                           package.yaml existence
  --cache FILE             Dependency cache
                           file (default: ".stack-to-nix.cache")
  -h,--help                Show this help text

Use this for stack projects. If a default.nix does not exist in the output directory, it will create a basic one with a mkStackPkgSet function.

Note:

If you find that there are missing files which should have been generated, remove .stack-to-nix.cache (The open issue is #57).

plan-to-nix

plan-to-nix - a stack to nix converter

Usage: plan-to-nix (-o|--output DIR) [--plan-json FILE] [--cabal-project FILE]
                   [--cache FILE]
  Generate a Nix expression for a Haskell package using Cabal

Available options:
  -o,--output DIR          Generate output in DIR
  --plan-json FILE         Override plan.json
                           location (default: "dist-newstyle/cache/plan.json")
  --cabal-project FILE     Override path to
                           cabal.project (default: "cabal.project")
  --cache FILE             Dependency cache file (default: ".nix-tools.cache")
  -h,--help                Show this help text

Use this for Cabal new-build projects (even if you don't have a cabal.project). Before running, you need to create a plan. For more information, see Cabal Projects in the user guide.

It will create a template default.nix in the output directory, unless that file already exists.

Inside the output directory, there will be another directory .plan.nix, which contains Nix expressions for all local packages, generated by cabal-to-nix. The output file pkgs.nix refers to these files.

Note:

If you find that there are missing files which should have been generated, remove .nix-tools.cache (The open issue is #57).

cabal-to-nix

Usage: cabal-to-nix FILE.cabal

This writes (to stdout) a Haskell.nix Nix expression for the given cabal package.

Normally, you do not need to run cabal-to-nix yourself. It is called by stack-to-nix and plan-to-nix.

Haskell.nix contains a library of functions for creating buildable package sets from their Nix expression descriptions. The library is what you get when importing Haskell.nix. It might be helpful to load the library in the Nix REPL to test things.

Data structures

Package Set

The result of mkPkgSet. This is an application of the NixOS module system.

{
  options = { ... };
  config = {
    hsPkgs = { ... };
    packages = { ... };
    compiler = {
      version = "X.Y.Z";
      nix-name = "ghcXYZ";
      packages = { ... };
    };
  };
}
AttributeTypeDescription
optionsModule optionsThe combination of all options set through the modules argument passed to mkPkgsSet.
configThe result of evaluating and applying the options with Haskell.nix
.hsPkgsAttrset of Haskell PackagesBuildable packages, created from packages
.packagesAttrset of Haskell Package descriptionsConfiguration for each package in hsPkgs
.compilerAttrset

Haskell Package description

The Haskell package descriptions are values of the pkgSet.config.packages attrset. These are not derivations, but just the configuration for building an individual package. The configuration options are described under packages.<name> in Module options.

Component description

The component descriptions are values of the pkgSet.config.packages.<package>.components attrset. These are not derivations, but just the configuration for building an individual component. The configuration options are described under packages.<name>.components.* in Module options.

Haskell Package

In Haskell.nix, a Haskell package is a derivation which has a components attribute. This derivation is actually just for the package Setup.hs script, and isn't very interesting. To actually use the package, look within the components structure.

components = {
  library = COMPONENT;
  exes = { NAME = COMPONENT; };
  tests = { NAME = COMPONENT; };
  benchmarks = { NAME = COMPONENT; };
}

Component

In Haskell.nix, a component is a derivation corresponding to a Cabal component of a package.

Identifier

A package identifier is an attrset pair of name and version.

Extras

Extras allow adding more packages to the package set. These will be functions taking a single parameter hackage. They should return an attrset of package descriptions.

Modules

Modules are the primary method of configuring building of the package set. They are either:

  1. an attrset containing option declarations, or
  2. a function that returns an attrset containing option declarations.

If using the function form of a module, the following named parameters will be passed to it:

ArgumentTypeDescription
haskellLibattrsetThe haskellLib utility functions.
pkgsThe Nixpkgs collection.
pkgconfPkgsA mapping of cabal build-depends names to Nixpkgs packages. (TODO: more information about this)
buildModules
config
options

Top-level attributes

project'

Function that accepts attribute set with a src attribute and looks for stack.yaml file relative to it.

If file exists, it calls stackProject function. Otherwise it will call cabalProject function.

Example:

pkgs.haskell-nix.project' {
  # 'cleanGit' cleans a source directory based on the files known by git
  src = pkgs.haskell-nix.haskellLib.cleanGit {
    name = "haskell-nix-project";
    src = ./.;
  };
}

stackProject'

A function calling callStackToNix with all arguments.

Then feeding its result into mkStackPkgSet passing also pkg-def-extras and modules arguments.

Return value:

AttributeTypeDescription
hsPkgsAttrset of Haskell PackagesBuildable packages, created from packages
stack-nixprojectNix attribute of callStackToNix return value
shellForFunctionshellFor
ghcWithHoogleFunctionghcWithHoogle
ghcWithPackagesFunctionghcWithPackages

cabalProject'

A function calling callCabalProjectToNix with all arguments.

Then feeding its result into mkCabalProjectPkgSet passing also pkg-def-extras, extra-hackages and modules arguments.

Return value:

AttributeTypeDescription
hsPkgsAttrset of Haskell PackagesBuildable packages, created from packages
plan-nixprojectNix attribute of callCabalProjectToNix return value
index-stateindex-state attribute of callCabalProjectToNix return value
shellForFunctionshellFor
ghcWithHoogleFunctionghcWithHoogle
ghcWithPackagesFunctionghcWithPackages
projectCrossAttrsetLike pkgs.pkgsCross.<system> from nixpkgs p.projectCross.<system> returns the project results for cross compilation (where system is a member of nixpkgs lib.systems.examples). So p.projectCross.ghcjs.hsPkgs is the same as hsPkgs but compiled with ghcjs
projectVariantsAttrsetAttribute set of variant for the project, mapped from flake.variants config values
appendModuleFunctionRe-eval the project with an extra module (or module list).
extend and appendOverlaysFunctionModify a project, or add attributes, through overlays: p.extend(final: prev: { }). The overlays are carried-over projectCross and appendModule invocations.

project, cabalProject and stackProject

These versions of the function are the same as project', cabalProject' and stackProject', but hsPkgs attributes are also included in the return value directly. That way a package can be referenced as (project {...}).foo instead of (project' {...}).hsPkgs.foo.

mkStackPkgSet

Creates a package set based on the pkgs.nix output of stack-to-nix.

mkStackPkgSet =
    { stack-pkgs, pkg-def-extras ? [], modules ? []}: ...
ArgumentTypeDescription
stack-pkgsimport ./pkgs.nix — The imported file generated by stack‑to‑nix.
pkg‑def‑extrasList of ExtrasFor overriding the package set.
modulesList of ModulesFor overriding the package set.

Return value: a pkgSet

mkCabalProjectPkgSet

Creates a package set based on the pkgs.nix output of plan-to-nix.

mkCabalProjectPkgSet =
    { plan-pkgs, pkg-def-extras ? [], modules ? []}: ...
ArgumentTypeDescription
plan-pkgsimport ./pkgs.nix — The imported file generated by plan‑to‑nix.
pkg‑def‑extrasList of ExtrasFor overriding the package set.
modulesList of ModulesFor overriding the package set.

Return value: a pkgSet

mkPkgSet

This is the base function used by both mkStackPkgSet and mkCabalProjectPkgSet.

Return value: a pkgSet

snapshots

This is an attrset of hsPkgs packages from Stackage.

haskellPackages

A hsPkgs package set, which is one of the recent LTS Haskell releases from snapshots.

The chosen LTS is updated occasionally in Haskell.nix, though a manual process.

nix-tools

A derivation containing the nix-tools command-line tools.

callStackToNix

Runs stack-to-nix and produces the output needed for importAndFilterProject.

Example:

  pkgSet = mkStackPkgSet {
    stack-pkgs = (importAndFilterProject (callStackToNix {
      src = ./.;
    })).pkgs;
    pkg-def-extras = [];
    modules = [];
  };

callCabalProjectToNix

Runs cabal new-configure and plan-to-nix and produces the output needed for importAndFilterProject.

Example:

  pkgSet = mkCabalProjectPkgSet {
    plan-pkgs = (importAndFilterProject (callCabalProjectToNix {
      index-state = "2019-04-30T00:00:00Z";
      src = ./.;
    })).pkgs;
ArgumentTypeDescription
nameStringOptional name for better error messages.
srcPathLocation of the cabal project files.
compiler-nix-nameStringThe name of the ghc compiler to use eg. "ghc884"
index-stateTimestampOptional hackage index-state, eg. "2019-10-10T00:00:00Z".
index-sha256Sha256Optional hash of the truncated hackage index-state.
plan-sha256Sha256Optional hash of the plan-to-nix output (makes the plan-to-nix step a fixed output derivation).
cabalProjectStringOptional cabal project file contents (defaults to readFile "${src}/cabal.project").
cabalProjectLocalStringOptional cabal project file contents (defaults to readFile "${src}/cabal.project.local").
cabalProjectFreezeStringOptional cabal project file contents (defaults to readFile "${src}/cabal.project.freeze").
ghcDeprecated. Use compiler-nix-name instead. Optional ghc to use
nix-toolsOptional nix-tools to use
hpackOptional hpack to use
cabal-installOptional cabal-install to use
configureArgsStringOptional extra arguments to pass to cabal new-configure (--enable-tests is included by default, include --disable-tests to override that).

importAndFilterProject

Imports from a derivation created by callStackToNix or callCabalProjectToNix.

The result is an attrset with the following values:

AttributeTypeDescription
pkgsattrsetthat can be passed to mkStackPkgSet (as stack-pkgs) or mkCabalProjectPkgSet (as plan-pkgs).
nixthis can be built and cached so that the amount built in the evaluation phase is not too great (helps to avoid timeouts on Hydra).

hackage

stackage

fetchExternal

cleanSourceHaskell

cleanSourceHaskell = { src, name ? null }: ...

Filters a source tree removing common filenames that are not Haskell build sources.

This can avoid unecessary rebuilds when these files change.

It's recommended to provide name so that the source derivation remains constant regardless of how it was fetched.

Example:

src = pkgs.haskell-nix.cleanSourceHaskell {
  src = ./.;
  name = "myproject-src";
};

haskellSourceFilter

haskellSourceFilter = name: type: ...

This is a source filter function which cleans common build products and files not needed to do a Haskell build from a source directory.

It should be used with pkgs.lib.cleanSourceWith. Alternatively, use the convenience function cleanSourceHaskell.

haskellLib

Assorted functions for operating on Haskell.nix data. This is distinct from pkgs.haskell.lib in the current Nixpkgs Haskell Infrastructure.

collectComponents, collectComponents'

Extracts a selection of components from a Haskell package set.

This can be used to filter out all test suites or benchmarks of your project, so that they can be built in Hydra (see check if you want to run the tests as well as build them).

collectComponents' is an alias of collectComponents without predicate for filtering.

collectComponents =
    group: packageSel: haskellPackages: ...
collectComponents' = group: collectComponents (_: true)
ArgumentTypeDescription
groupStringA sub-component type.
packageSelA function Package -> BoolA predicate to filter packages with.
haskellPackagesPackage setAll packages in the build.

Return value: a recursive attrset mapping package names → component names → components.

Example:

tests = collectComponents "tests" (package: package.identifier.name == "mypackage") hsPkgs;

Will result in moving derivations from hsPkgs.mypackage.components.tests.unit-tests to tests.mypackage.unit-tests.

collectChecks, collectChecks'

These are just like collectComponents and collectComponents', except that they collect the checks attributes of packages (which aren't components, and so can't be collected by the other functions.

check

This function turns a derivation that builds a test into one to run it.

ArgumentTypeDescription
drvDerivationOne of $pkg.components.tests.$test.

For convenience $pkg.components.tests are mapped with this function to $pkg.checks.

This function is intended for use with tests but it should also work for exes and benchmarks if you just want to run them to make sure they execute.

subComponentTypes

Sub-component types identify components and are one of:

  • sublibs
  • foreignlibs
  • exes
  • tests
  • benchmarks

Project functions

These functions are included in the project return values. In the past they also existed within project.hsPkgs, but have now been removed from there.

shellFor

Create a nix-shell development environment for developing one or more packages with ghci or cabal v2-build (but not Stack).

shellFor =
    { packages, withHoogle ? true, exactDeps ? false, ...}: ...
ArgumentTypeDescription
packagesFunctionPackage selection function. It takes a list of Haskell packages and returns a subset of these packages.
componentsFunctionSimilar to packages, by default all the components of the selected packages are selected.
additionalFunctionSimilar to packages, but the selected packages are built and included in ghc-pkg list (not just their dependencies).
withHoogleBooleanWhether to build a Hoogle documentation index and provide the hoogle command.
exactDepsBooleanPrevents the Cabal solver from choosing any package dependency other than what are in the package set.
toolsFunctionAttrSet of tools to make available e.g. { cabal = "3.2.0.0"; } or { cabal = { version = "3.2.0.0"; }; }. If an AttrSet is provided for a tool, the additional arguments will be passed to the function creating the derivation for that tool. So you can provide an index-state or a materialized argument like that { cabal = { version = "3.2.0.0"; index-state = "2020-10-30T00:00:00Z"; materialized = ./cabal.materialized; }; } for example. You can specify and materialize the version of hoogle used to construct the hoogle index by including something like { hoogle = { version = "5.0.17.15"; index-state = "2020-05-31T00:00:00Z"; materialized = ./hoogle.materialized; }. Uses a default version of hoogle if omitted.
inputsFromListList of other shells to include in this one. The buildInputs and nativeBuildInputs of each will be included using mkShell.
crossPlatformsFunctionPlatform selection function for cross compilation targets to support eg. ps: with ps; [ghcjs mingwW64] (see nixpkgs lib.systems.examples for list of platform names).
{ ... }AttrsetAll the other arguments are passed to mkDerivation.

Return value: a derivation

⚠️ Warning:

exactDeps = true will set the CABAL_CONFIG environment variable to disable remote package servers. This is a known limitation which we would like to solve. Use exactDeps = false if this is a problem.

ghcWithPackages

Creates a nix-shell development environment including the given packages selected from this package set.

Parameter: a package selection function.

Return value: a derivation

Example:

haskell.haskellPackages.ghcWithPackages (ps: with ps; [ lens conduit ])

ghcWithHoogle

The same as ghcWithPackages, except, a hoogle command with a Hoogle documentation index of the packages will be included in the shell.

Haskell.nix modules options for packages and components.

!!! note "Generated" This documentation is generated from Nix sources in the modules subdirectory using scripts/update-docs.nix

Configuration Options

_module.args

Additional arguments passed to each module in addition to ones like lib, config, and pkgs, modulesPath.

This option is also available to all submodules. Submodules do not inherit args from their parent module, nor do they provide args to their parent module or sibling submodules. The sole exception to this is the argument name which is provided by parent modules to a submodule and contains the attribute name the submodule is bound to, or a unique generated name if it is not bound to an attribute.

Some arguments are already passed by default, of which the following cannot be changed with this option:

  • {var}lib: The nixpkgs library.

  • {var}config: The results of all options after merging the values from all modules together.

  • {var}options: The options declared in all modules.

  • {var}specialArgs: The specialArgs argument passed to evalModules.

  • All attributes of {var}specialArgs

    Whereas option values can generally depend on other option values thanks to laziness, this does not apply to imports, which must be computed statically before anything else.

    For this reason, callers of the module system can provide specialArgs which are available during import resolution.

    For NixOS, specialArgs includes {var}modulesPath, which allows you to import extra modules from the nixpkgs package tree without having to somehow make the module aware of the location of the nixpkgs or NixOS directories.

    { modulesPath, ... }: {
      imports = [
        (modulesPath + "/profiles/minimal.nix")
      ];
    }
    

For NixOS, the default value for this option includes at least this argument:

  • {var}pkgs: The nixpkgs package set according to the {option}nixpkgs.pkgs option.

Type: lazy attribute set of raw value

No Default

No Example

bootPkgs

Type: list of string

No Default

No Example

buildable

Type: boolean

Default: true

No Example

cabal.compiler

Type: unspecified value

No Default

No Example

cabal.system

Type: unspecified value

No Default

No Example

compiler.nix-name

Type: string

No Default

No Example

compiler.packages

Type: attribute set of string

No Default

No Example

compiler.version

Type: string

No Default

No Example

configureAllComponents

If set all the components in the package are configured (useful for cabal-doctest).

Type: boolean

Default: false

No Example

configureFlags

Type: list of string

Default: []

No Example

contentAddressed

Build content addressed derivation, requires Nix to have experimental feature ca-derivations enabled.

Type: boolean

Default: false

No Example

doCheck

Type: boolean

Default: true

No Example

doCoverage

Enable production of test coverage reports.

Type: boolean

Default: false

No Example

doCrossCheck

Run doCheck also in cross compilation settings. This can be tricky as the test logic must know how to run the tests on the target.

Type: boolean

Default: false

No Example

doExactConfig

Type: boolean

Default: false

No Example

doHaddock

Enable building of the Haddock documentation from the annotated Haskell source code.

Type: boolean

Default: true

No Example

doHoogle

Also build a hoogle index.

Type: boolean

Default: true

No Example

doHyperlinkSource

Link documentation to the source code.

Type: boolean

Default: true

No Example

doQuickjump

Generate an index for interactive documentation navigation.

Type: boolean

Default: true

No Example

dontPatchELF

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

Type: boolean

Default: true

No Example

dontStrip

If set, libraries and executables are not stripped.

Type: boolean

Default: true

No Example

enableDeadCodeElimination

If set, enables split sections for link-time dead-code stripping. Only applies to Linux

Type: boolean

Default: true

No Example

enableLibraryProfiling

Type: boolean

Default: false

No Example

enableProfiling

Type: boolean

Default: false

No Example

enableSeparateDataOutput

Type: boolean

Default: true

No Example

enableShared

If set, enables building shared libraries.

Type: boolean

Default: true

No Example

enableStatic

If set, enables building static libraries and executables.

Type: boolean

Default: true

No Example

errorHandler

Type: unspecified value

No Default

No Example

evalPackages

The evalPackages that will be used when building hoogle and shell tools.

Type: unspecified value

No Default

No Example

ghc.package

Type: package

Default: "pkgs.buildPackages.haskell-nix.compiler.${config.compiler.nix-name}"

No Example

ghcOptions

Type: list of string

Default: []

No Example

hackage.configs

Type: unspecified value

No Default

No Example

hackage.db

Type: unspecified value

No Default

No Example

hardeningDisable

Type: list of string

Default: []

No Example

hsPkgs

Type: unspecified value

No Default

No Example

inputMap

Type: attribute set of unspecified value

Default: {}

No Example

keepSource

Keep component source in the store in a source output

Type: boolean

Default: false

No Example

nonReinstallablePkgs

Type: list of string

No Default

No Example

packages

Type: attribute set of (submodule)

No Default

No Example

packages..allComponent

The merged dependencies of all other components

Type: submodule

No Default

No Example

packages..allComponent.asmSources

Type: list of unspecified value

Default: []

No Example

packages..allComponent.build-tools

Type: list of unspecified value

Default: []

No Example

packages..allComponent.buildable

Type: boolean

Default: true

No Example

packages..allComponent.cSources

Type: list of unspecified value

Default: []

No Example

packages..allComponent.cmmSources

Type: list of unspecified value

Default: []

No Example

packages..allComponent.configureAllComponents

If set all the components in the package are configured (useful for cabal-doctest).

Type: boolean

Default: false

No Example

packages..allComponent.configureFlags

Type: list of string

Default: []

No Example

packages..allComponent.contentAddressed

Build content addressed derivation, requires Nix to have experimental feature ca-derivations enabled.

Type: boolean

Default: false

No Example

packages..allComponent.cxxSources

Type: list of unspecified value

Default: []

No Example

packages..allComponent.depends

Type: list of unspecified value

Default: []

No Example

packages..allComponent.doCheck

Type: boolean

Default: true

No Example

packages..allComponent.doCoverage

Enable production of test coverage reports.

Type: boolean

Default: false

No Example

packages..allComponent.doCrossCheck

Run doCheck also in cross compilation settings. This can be tricky as the test logic must know how to run the tests on the target.

Type: boolean

Default: false

No Example

packages..allComponent.doExactConfig

Type: boolean

Default: false

No Example

packages..allComponent.doHaddock

Enable building of the Haddock documentation from the annotated Haskell source code.

Type: boolean

Default: true

No Example

packages..allComponent.doHoogle

Also build a hoogle index.

Type: boolean

Default: true

No Example

packages..allComponent.doHyperlinkSource

Link documentation to the source code.

Type: boolean

Default: true

No Example

packages..allComponent.doQuickjump

Generate an index for interactive documentation navigation.

Type: boolean

Default: true

No Example

packages..allComponent.dontPatchELF

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

Type: boolean

Default: true

No Example

packages..allComponent.dontStrip

If set, libraries and executables are not stripped.

Type: boolean

Default: true

No Example

packages..allComponent.enableDeadCodeElimination

If set, enables split sections for link-time dead-code stripping. Only applies to Linux

Type: boolean

Default: true

No Example

packages..allComponent.enableLibraryProfiling

Type: boolean

Default: false

No Example

packages..allComponent.enableProfiling

Type: boolean

Default: false

No Example

packages..allComponent.enableSeparateDataOutput

Type: boolean

Default: true

No Example

packages..allComponent.enableShared

If set, enables building shared libraries.

Type: boolean

Default: true

No Example

packages..allComponent.enableStatic

If set, enables building static libraries and executables.

Type: boolean

Default: true

No Example

packages..allComponent.extraSrcFiles

Type: list of unspecified value

Default: []

No Example

packages..allComponent.frameworks

Type: list of package

Default: []

No Example

packages..allComponent.ghcOptions

Type: list of string

Default: []

No Example

packages..allComponent.hardeningDisable

Type: list of string

Default: []

No Example

packages..allComponent.hsSourceDirs

Type: list of unspecified value

Default: ["."]

No Example

packages..allComponent.includeDirs

Type: list of unspecified value

Default: []

No Example

packages..allComponent.includes

Type: list of unspecified value

Default: []

No Example

packages..allComponent.jsSources

Type: list of unspecified value

Default: []

No Example

packages..allComponent.keepSource

Keep component source in the store in a source output

Type: boolean

Default: false

No Example

packages..allComponent.libs

Type: list of (null or package or list of package)

Default: []

No Example

packages..allComponent.mainPath

Type: list of unspecified value

Default: []

No Example

packages..allComponent.modules

Type: list of unspecified value

Default: []

No Example

packages..allComponent.pkgconfig

Type: list of list of package

Default: []

No Example

packages..allComponent.planned

Set to true by plan-to-nix for any component that was included in the plan.json file.

Type: boolean

Default: false

No Example

packages..allComponent.platforms

Type: null or (list of unspecified value)

Default: null

No Example

packages..allComponent.plugins

Type: list of (submodule)

Default: []

No Example

packages..allComponent.plugins.*.args

Type: list of string

Default: []

No Example

packages..allComponent.plugins.*.library

Type: unspecified value

No Default

No Example

packages..allComponent.plugins.*.moduleName

Type: string

No Default

No Example

packages..allComponent.postBuild

Type: null or string

Default: null

No Example

packages..allComponent.postCheck

Type: null or string

Default: null

No Example

packages..allComponent.postConfigure

Type: null or string

Default: null

No Example

packages..allComponent.postHaddock

Type: null or string

Default: null

No Example

packages..allComponent.postInstall

Type: null or string

Default: null

No Example

packages..allComponent.postUnpack

Type: null or string

Default: null

No Example

packages..allComponent.preBuild

Type: null or string

Default: null

No Example

packages..allComponent.preCheck

Type: null or string

Default: null

No Example

packages..allComponent.preConfigure

Type: null or string

Default: null

No Example

packages..allComponent.preHaddock

Type: null or string

Default: null

No Example

packages..allComponent.preInstall

Type: null or string

Default: null

No Example

packages..allComponent.preUnpack

Type: null or strings concatenated with "\n"

Default: null

No Example

packages..allComponent.profilingDetail

Type: null or string

Default: "default"

No Example

packages..allComponent.setupBuildFlags

Type: list of string

Default: []

No Example

packages..allComponent.setupHaddockFlags

Type: list of string

Default: []

No Example

packages..allComponent.setupInstallFlags

Type: list of string

Default: []

No Example

packages..allComponent.shellHook

Hook to run when entering a shell

Type: unspecified value

Default: ""

No Example

packages..allComponent.testFlags

Type: list of string

Default: []

No Example

packages..allComponent.testWrapper

A command to run for executing tests in checkPhase, which takes the original test command as its arguments.

Type: list of string

Default: []

Example:

"echo"

packages..allComponent.writeHieFiles

Write component .hie files in the store in a hie output

Type: boolean

Default: false

No Example

packages..buildable

Type: boolean

Default: true

No Example

packages..cabal-generator

Type: null or string

Default: null

No Example

packages..components.benchmarks

Type: attribute set of (submodule)

Default: {}

No Example

packages..components.benchmarks..asmSources

Type: list of unspecified value

Default: []

No Example

packages..components.benchmarks..build-tools

Type: list of unspecified value

Default: []

No Example

packages..components.benchmarks..buildable

Type: boolean

Default: true

No Example

packages..components.benchmarks..cSources

Type: list of unspecified value

Default: []

No Example

packages..components.benchmarks..cmmSources

Type: list of unspecified value

Default: []

No Example

packages..components.benchmarks..configureAllComponents

If set all the components in the package are configured (useful for cabal-doctest).

Type: boolean

Default: false

No Example

packages..components.benchmarks..configureFlags

Type: list of string

Default: []

No Example

packages..components.benchmarks..contentAddressed

Build content addressed derivation, requires Nix to have experimental feature ca-derivations enabled.

Type: boolean

Default: false

No Example

packages..components.benchmarks..cxxSources

Type: list of unspecified value

Default: []

No Example

packages..components.benchmarks..depends

Type: list of unspecified value

Default: []

No Example

packages..components.benchmarks..doCheck

Type: boolean

Default: true

No Example

packages..components.benchmarks..doCoverage

Enable production of test coverage reports.

Type: boolean

Default: false

No Example

packages..components.benchmarks..doCrossCheck

Run doCheck also in cross compilation settings. This can be tricky as the test logic must know how to run the tests on the target.

Type: boolean

Default: false

No Example

packages..components.benchmarks..doExactConfig

Type: boolean

Default: false

No Example

packages..components.benchmarks..doHaddock

Enable building of the Haddock documentation from the annotated Haskell source code.

Type: boolean

Default: true

No Example

packages..components.benchmarks..doHoogle

Also build a hoogle index.

Type: boolean

Default: true

No Example

packages..components.benchmarks..doHyperlinkSource

Link documentation to the source code.

Type: boolean

Default: true

No Example

packages..components.benchmarks..doQuickjump

Generate an index for interactive documentation navigation.

Type: boolean

Default: true

No Example

packages..components.benchmarks..dontPatchELF

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

Type: boolean

Default: true

No Example

packages..components.benchmarks..dontStrip

If set, libraries and executables are not stripped.

Type: boolean

Default: true

No Example

packages..components.benchmarks..enableDeadCodeElimination

If set, enables split sections for link-time dead-code stripping. Only applies to Linux

Type: boolean

Default: true

No Example

packages..components.benchmarks..enableLibraryProfiling

Type: boolean

Default: false

No Example

packages..components.benchmarks..enableProfiling

Type: boolean

Default: false

No Example

packages..components.benchmarks..enableSeparateDataOutput

Type: boolean

Default: true

No Example

packages..components.benchmarks..enableShared

If set, enables building shared libraries.

Type: boolean

Default: true

No Example

packages..components.benchmarks..enableStatic

If set, enables building static libraries and executables.

Type: boolean

Default: true

No Example

packages..components.benchmarks..extraSrcFiles

Type: list of unspecified value

Default: []

No Example

packages..components.benchmarks..frameworks

Type: list of package

Default: []

No Example

packages..components.benchmarks..ghcOptions

Type: list of string

Default: []

No Example

packages..components.benchmarks..hardeningDisable

Type: list of string

Default: []

No Example

packages..components.benchmarks..hsSourceDirs

Type: list of unspecified value

Default: ["."]

No Example

packages..components.benchmarks..includeDirs

Type: list of unspecified value

Default: []

No Example

packages..components.benchmarks..includes

Type: list of unspecified value

Default: []

No Example

packages..components.benchmarks..jsSources

Type: list of unspecified value

Default: []

No Example

packages..components.benchmarks..keepSource

Keep component source in the store in a source output

Type: boolean

Default: false

No Example

packages..components.benchmarks..libs

Type: list of (null or package or list of package)

Default: []

No Example

packages..components.benchmarks..mainPath

Type: list of unspecified value

Default: []

No Example

packages..components.benchmarks..modules

Type: list of unspecified value

Default: []

No Example

packages..components.benchmarks..pkgconfig

Type: list of list of package

Default: []

No Example

packages..components.benchmarks..planned

Set to true by plan-to-nix for any component that was included in the plan.json file.

Type: boolean

Default: false

No Example

packages..components.benchmarks..platforms

Type: null or (list of unspecified value)

Default: null

No Example

packages..components.benchmarks..plugins

Type: list of (submodule)

Default: []

No Example

packages..components.benchmarks..plugins.*.args

Type: list of string

Default: []

No Example

packages..components.benchmarks..plugins.*.library

Type: unspecified value

No Default

No Example

packages..components.benchmarks..plugins.*.moduleName

Type: string

No Default

No Example

packages..components.benchmarks..postBuild

Type: null or string

Default: null

No Example

packages..components.benchmarks..postCheck

Type: null or string

Default: null

No Example

packages..components.benchmarks..postConfigure

Type: null or string

Default: null

No Example

packages..components.benchmarks..postHaddock

Type: null or string

Default: null

No Example

packages..components.benchmarks..postInstall

Type: null or string

Default: null

No Example

packages..components.benchmarks..postUnpack

Type: null or string

Default: null

No Example

packages..components.benchmarks..preBuild

Type: null or string

Default: null

No Example

packages..components.benchmarks..preCheck

Type: null or string

Default: null

No Example

packages..components.benchmarks..preConfigure

Type: null or string

Default: null

No Example

packages..components.benchmarks..preHaddock

Type: null or string

Default: null

No Example

packages..components.benchmarks..preInstall

Type: null or string

Default: null

No Example

packages..components.benchmarks..preUnpack

Type: null or strings concatenated with "\n"

Default: null

No Example

packages..components.benchmarks..profilingDetail

Type: null or string

Default: "default"

No Example

packages..components.benchmarks..setupBuildFlags

Type: list of string

Default: []

No Example

packages..components.benchmarks..setupHaddockFlags

Type: list of string

Default: []

No Example

packages..components.benchmarks..setupInstallFlags

Type: list of string

Default: []

No Example

packages..components.benchmarks..shellHook

Hook to run when entering a shell

Type: unspecified value

Default: ""

No Example

packages..components.benchmarks..testFlags

Type: list of string

Default: []

No Example

packages..components.benchmarks..testWrapper

A command to run for executing tests in checkPhase, which takes the original test command as its arguments.

Type: list of string

Default: []

Example:

"echo"

packages..components.benchmarks..writeHieFiles

Write component .hie files in the store in a hie output

Type: boolean

Default: false

No Example

packages..components.exes

Type: attribute set of (submodule)

Default: {}

No Example

packages..components.exes..asmSources

Type: list of unspecified value

Default: []

No Example

packages..components.exes..build-tools

Type: list of unspecified value

Default: []

No Example

packages..components.exes..buildable

Type: boolean

Default: true

No Example

packages..components.exes..cSources

Type: list of unspecified value

Default: []

No Example

packages..components.exes..cmmSources

Type: list of unspecified value

Default: []

No Example

packages..components.exes..configureAllComponents

If set all the components in the package are configured (useful for cabal-doctest).

Type: boolean

Default: false

No Example

packages..components.exes..configureFlags

Type: list of string

Default: []

No Example

packages..components.exes..contentAddressed

Build content addressed derivation, requires Nix to have experimental feature ca-derivations enabled.

Type: boolean

Default: false

No Example

packages..components.exes..cxxSources

Type: list of unspecified value

Default: []

No Example

packages..components.exes..depends

Type: list of unspecified value

Default: []

No Example

packages..components.exes..doCheck

Type: boolean

Default: true

No Example

packages..components.exes..doCoverage

Enable production of test coverage reports.

Type: boolean

Default: false

No Example

packages..components.exes..doCrossCheck

Run doCheck also in cross compilation settings. This can be tricky as the test logic must know how to run the tests on the target.

Type: boolean

Default: false

No Example

packages..components.exes..doExactConfig

Type: boolean

Default: false

No Example

packages..components.exes..doHaddock

Enable building of the Haddock documentation from the annotated Haskell source code.

Type: boolean

Default: true

No Example

packages..components.exes..doHoogle

Also build a hoogle index.

Type: boolean

Default: true

No Example

packages..components.exes..doHyperlinkSource

Link documentation to the source code.

Type: boolean

Default: true

No Example

packages..components.exes..doQuickjump

Generate an index for interactive documentation navigation.

Type: boolean

Default: true

No Example

packages..components.exes..dontPatchELF

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

Type: boolean

Default: true

No Example

packages..components.exes..dontStrip

If set, libraries and executables are not stripped.

Type: boolean

Default: true

No Example

packages..components.exes..enableDeadCodeElimination

If set, enables split sections for link-time dead-code stripping. Only applies to Linux

Type: boolean

Default: true

No Example

packages..components.exes..enableLibraryProfiling

Type: boolean

Default: false

No Example

packages..components.exes..enableProfiling

Type: boolean

Default: false

No Example

packages..components.exes..enableSeparateDataOutput

Type: boolean

Default: true

No Example

packages..components.exes..enableShared

If set, enables building shared libraries.

Type: boolean

Default: true

No Example

packages..components.exes..enableStatic

If set, enables building static libraries and executables.

Type: boolean

Default: true

No Example

packages..components.exes..extraSrcFiles

Type: list of unspecified value

Default: []

No Example

packages..components.exes..frameworks

Type: list of package

Default: []

No Example

packages..components.exes..ghcOptions

Type: list of string

Default: []

No Example

packages..components.exes..hardeningDisable

Type: list of string

Default: []

No Example

packages..components.exes..hsSourceDirs

Type: list of unspecified value

Default: ["."]

No Example

packages..components.exes..includeDirs

Type: list of unspecified value

Default: []

No Example

packages..components.exes..includes

Type: list of unspecified value

Default: []

No Example

packages..components.exes..jsSources

Type: list of unspecified value

Default: []

No Example

packages..components.exes..keepSource

Keep component source in the store in a source output

Type: boolean

Default: false

No Example

packages..components.exes..libs

Type: list of (null or package or list of package)

Default: []

No Example

packages..components.exes..mainPath

Type: list of unspecified value

Default: []

No Example

packages..components.exes..modules

Type: list of unspecified value

Default: []

No Example

packages..components.exes..pkgconfig

Type: list of list of package

Default: []

No Example

packages..components.exes..planned

Set to true by plan-to-nix for any component that was included in the plan.json file.

Type: boolean

Default: false

No Example

packages..components.exes..platforms

Type: null or (list of unspecified value)

Default: null

No Example

packages..components.exes..plugins

Type: list of (submodule)

Default: []

No Example

packages..components.exes..plugins.*.args

Type: list of string

Default: []

No Example

packages..components.exes..plugins.*.library

Type: unspecified value

No Default

No Example

packages..components.exes..plugins.*.moduleName

Type: string

No Default

No Example

packages..components.exes..postBuild

Type: null or string

Default: null

No Example

packages..components.exes..postCheck

Type: null or string

Default: null

No Example

packages..components.exes..postConfigure

Type: null or string

Default: null

No Example

packages..components.exes..postHaddock

Type: null or string

Default: null

No Example

packages..components.exes..postInstall

Type: null or string

Default: null

No Example

packages..components.exes..postUnpack

Type: null or string

Default: null

No Example

packages..components.exes..preBuild

Type: null or string

Default: null

No Example

packages..components.exes..preCheck

Type: null or string

Default: null

No Example

packages..components.exes..preConfigure

Type: null or string

Default: null

No Example

packages..components.exes..preHaddock

Type: null or string

Default: null

No Example

packages..components.exes..preInstall

Type: null or string

Default: null

No Example

packages..components.exes..preUnpack

Type: null or strings concatenated with "\n"

Default: null

No Example

packages..components.exes..profilingDetail

Type: null or string

Default: "default"

No Example

packages..components.exes..setupBuildFlags

Type: list of string

Default: []

No Example

packages..components.exes..setupHaddockFlags

Type: list of string

Default: []

No Example

packages..components.exes..setupInstallFlags

Type: list of string

Default: []

No Example

packages..components.exes..shellHook

Hook to run when entering a shell

Type: unspecified value

Default: ""

No Example

packages..components.exes..testFlags

Type: list of string

Default: []

No Example

packages..components.exes..testWrapper

A command to run for executing tests in checkPhase, which takes the original test command as its arguments.

Type: list of string

Default: []

Example:

"echo"

packages..components.exes..writeHieFiles

Write component .hie files in the store in a hie output

Type: boolean

Default: false

No Example

packages..components.foreignlibs

Type: attribute set of (submodule)

Default: {}

No Example

packages..components.foreignlibs..asmSources

Type: list of unspecified value

Default: []

No Example

packages..components.foreignlibs..build-tools

Type: list of unspecified value

Default: []

No Example

packages..components.foreignlibs..buildable

Type: boolean

Default: true

No Example

packages..components.foreignlibs..cSources

Type: list of unspecified value

Default: []

No Example

packages..components.foreignlibs..cmmSources

Type: list of unspecified value

Default: []

No Example

packages..components.foreignlibs..configureAllComponents

If set all the components in the package are configured (useful for cabal-doctest).

Type: boolean

Default: false

No Example

packages..components.foreignlibs..configureFlags

Type: list of string

Default: []

No Example

packages..components.foreignlibs..contentAddressed

Build content addressed derivation, requires Nix to have experimental feature ca-derivations enabled.

Type: boolean

Default: false

No Example

packages..components.foreignlibs..cxxSources

Type: list of unspecified value

Default: []

No Example

packages..components.foreignlibs..depends

Type: list of unspecified value

Default: []

No Example

packages..components.foreignlibs..doCheck

Type: boolean

Default: true

No Example

packages..components.foreignlibs..doCoverage

Enable production of test coverage reports.

Type: boolean

Default: false

No Example

packages..components.foreignlibs..doCrossCheck

Run doCheck also in cross compilation settings. This can be tricky as the test logic must know how to run the tests on the target.

Type: boolean

Default: false

No Example

packages..components.foreignlibs..doExactConfig

Type: boolean

Default: false

No Example

packages..components.foreignlibs..doHaddock

Enable building of the Haddock documentation from the annotated Haskell source code.

Type: boolean

Default: true

No Example

packages..components.foreignlibs..doHoogle

Also build a hoogle index.

Type: boolean

Default: true

No Example

packages..components.foreignlibs..doHyperlinkSource

Link documentation to the source code.

Type: boolean

Default: true

No Example

packages..components.foreignlibs..doQuickjump

Generate an index for interactive documentation navigation.

Type: boolean

Default: true

No Example

packages..components.foreignlibs..dontPatchELF

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

Type: boolean

Default: true

No Example

packages..components.foreignlibs..dontStrip

If set, libraries and executables are not stripped.

Type: boolean

Default: true

No Example

packages..components.foreignlibs..enableDeadCodeElimination

If set, enables split sections for link-time dead-code stripping. Only applies to Linux

Type: boolean

Default: true

No Example

packages..components.foreignlibs..enableLibraryProfiling

Type: boolean

Default: false

No Example

packages..components.foreignlibs..enableProfiling

Type: boolean

Default: false

No Example

packages..components.foreignlibs..enableSeparateDataOutput

Type: boolean

Default: true

No Example

packages..components.foreignlibs..enableShared

If set, enables building shared libraries.

Type: boolean

Default: true

No Example

packages..components.foreignlibs..enableStatic

If set, enables building static libraries and executables.

Type: boolean

Default: true

No Example

packages..components.foreignlibs..extraSrcFiles

Type: list of unspecified value

Default: []

No Example

packages..components.foreignlibs..frameworks

Type: list of package

Default: []

No Example

packages..components.foreignlibs..ghcOptions

Type: list of string

Default: []

No Example

packages..components.foreignlibs..hardeningDisable

Type: list of string

Default: []

No Example

packages..components.foreignlibs..hsSourceDirs

Type: list of unspecified value

Default: ["."]

No Example

packages..components.foreignlibs..includeDirs

Type: list of unspecified value

Default: []

No Example

packages..components.foreignlibs..includes

Type: list of unspecified value

Default: []

No Example

packages..components.foreignlibs..jsSources

Type: list of unspecified value

Default: []

No Example

packages..components.foreignlibs..keepSource

Keep component source in the store in a source output

Type: boolean

Default: false

No Example

packages..components.foreignlibs..libs

Type: list of (null or package or list of package)

Default: []

No Example

packages..components.foreignlibs..mainPath

Type: list of unspecified value

Default: []

No Example

packages..components.foreignlibs..modules

Type: list of unspecified value

Default: []

No Example

packages..components.foreignlibs..pkgconfig

Type: list of list of package

Default: []

No Example

packages..components.foreignlibs..planned

Set to true by plan-to-nix for any component that was included in the plan.json file.

Type: boolean

Default: false

No Example

packages..components.foreignlibs..platforms

Type: null or (list of unspecified value)

Default: null

No Example

packages..components.foreignlibs..plugins

Type: list of (submodule)

Default: []

No Example

packages..components.foreignlibs..plugins.*.args

Type: list of string

Default: []

No Example

packages..components.foreignlibs..plugins.*.library

Type: unspecified value

No Default

No Example

packages..components.foreignlibs..plugins.*.moduleName

Type: string

No Default

No Example

packages..components.foreignlibs..postBuild

Type: null or string

Default: null

No Example

packages..components.foreignlibs..postCheck

Type: null or string

Default: null

No Example

packages..components.foreignlibs..postConfigure

Type: null or string

Default: null

No Example

packages..components.foreignlibs..postHaddock

Type: null or string

Default: null

No Example

packages..components.foreignlibs..postInstall

Type: null or string

Default: null

No Example

packages..components.foreignlibs..postUnpack

Type: null or string

Default: null

No Example

packages..components.foreignlibs..preBuild

Type: null or string

Default: null

No Example

packages..components.foreignlibs..preCheck

Type: null or string

Default: null

No Example

packages..components.foreignlibs..preConfigure

Type: null or string

Default: null

No Example

packages..components.foreignlibs..preHaddock

Type: null or string

Default: null

No Example

packages..components.foreignlibs..preInstall

Type: null or string

Default: null

No Example

packages..components.foreignlibs..preUnpack

Type: null or strings concatenated with "\n"

Default: null

No Example

packages..components.foreignlibs..profilingDetail

Type: null or string

Default: "default"

No Example

packages..components.foreignlibs..setupBuildFlags

Type: list of string

Default: []

No Example

packages..components.foreignlibs..setupHaddockFlags

Type: list of string

Default: []

No Example

packages..components.foreignlibs..setupInstallFlags

Type: list of string

Default: []

No Example

packages..components.foreignlibs..shellHook

Hook to run when entering a shell

Type: unspecified value

Default: ""

No Example

packages..components.foreignlibs..testFlags

Type: list of string

Default: []

No Example

packages..components.foreignlibs..testWrapper

A command to run for executing tests in checkPhase, which takes the original test command as its arguments.

Type: list of string

Default: []

Example:

"echo"

packages..components.foreignlibs..writeHieFiles

Write component .hie files in the store in a hie output

Type: boolean

Default: false

No Example

packages..components.library

Type: null or (submodule)

Default: null

No Example

packages..components.library.asmSources

Type: list of unspecified value

Default: []

No Example

packages..components.library.build-tools

Type: list of unspecified value

Default: []

No Example

packages..components.library.buildable

Type: boolean

Default: true

No Example

packages..components.library.cSources

Type: list of unspecified value

Default: []

No Example

packages..components.library.cmmSources

Type: list of unspecified value

Default: []

No Example

packages..components.library.configureAllComponents

If set all the components in the package are configured (useful for cabal-doctest).

Type: boolean

Default: false

No Example

packages..components.library.configureFlags

Type: list of string

Default: []

No Example

packages..components.library.contentAddressed

Build content addressed derivation, requires Nix to have experimental feature ca-derivations enabled.

Type: boolean

Default: false

No Example

packages..components.library.cxxSources

Type: list of unspecified value

Default: []

No Example

packages..components.library.depends

Type: list of unspecified value

Default: []

No Example

packages..components.library.doCheck

Type: boolean

Default: true

No Example

packages..components.library.doCoverage

Enable production of test coverage reports.

Type: boolean

Default: false

No Example

packages..components.library.doCrossCheck

Run doCheck also in cross compilation settings. This can be tricky as the test logic must know how to run the tests on the target.

Type: boolean

Default: false

No Example

packages..components.library.doExactConfig

Type: boolean

Default: false

No Example

packages..components.library.doHaddock

Enable building of the Haddock documentation from the annotated Haskell source code.

Type: boolean

Default: true

No Example

packages..components.library.doHoogle

Also build a hoogle index.

Type: boolean

Default: true

No Example

packages..components.library.doHyperlinkSource

Link documentation to the source code.

Type: boolean

Default: true

No Example

packages..components.library.doQuickjump

Generate an index for interactive documentation navigation.

Type: boolean

Default: true

No Example

packages..components.library.dontPatchELF

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

Type: boolean

Default: true

No Example

packages..components.library.dontStrip

If set, libraries and executables are not stripped.

Type: boolean

Default: true

No Example

packages..components.library.enableDeadCodeElimination

If set, enables split sections for link-time dead-code stripping. Only applies to Linux

Type: boolean

Default: true

No Example

packages..components.library.enableLibraryProfiling

Type: boolean

Default: false

No Example

packages..components.library.enableProfiling

Type: boolean

Default: false

No Example

packages..components.library.enableSeparateDataOutput

Type: boolean

Default: true

No Example

packages..components.library.enableShared

If set, enables building shared libraries.

Type: boolean

Default: true

No Example

packages..components.library.enableStatic

If set, enables building static libraries and executables.

Type: boolean

Default: true

No Example

packages..components.library.extraSrcFiles

Type: list of unspecified value

Default: []

No Example

packages..components.library.frameworks

Type: list of package

Default: []

No Example

packages..components.library.ghcOptions

Type: list of string

Default: []

No Example

packages..components.library.hardeningDisable

Type: list of string

Default: []

No Example

packages..components.library.hsSourceDirs

Type: list of unspecified value

Default: ["."]

No Example

packages..components.library.includeDirs

Type: list of unspecified value

Default: []

No Example

packages..components.library.includes

Type: list of unspecified value

Default: []

No Example

packages..components.library.jsSources

Type: list of unspecified value

Default: []

No Example

packages..components.library.keepSource

Keep component source in the store in a source output

Type: boolean

Default: false

No Example

packages..components.library.libs

Type: list of (null or package or list of package)

Default: []

No Example

packages..components.library.mainPath

Type: list of unspecified value

Default: []

No Example

packages..components.library.modules

Type: list of unspecified value

Default: []

No Example

packages..components.library.pkgconfig

Type: list of list of package

Default: []

No Example

packages..components.library.planned

Set to true by plan-to-nix for any component that was included in the plan.json file.

Type: boolean

Default: false

No Example

packages..components.library.platforms

Type: null or (list of unspecified value)

Default: null

No Example

packages..components.library.plugins

Type: list of (submodule)

Default: []

No Example

packages..components.library.plugins.*.args

Type: list of string

Default: []

No Example

packages..components.library.plugins.*.library

Type: unspecified value

No Default

No Example

packages..components.library.plugins.*.moduleName

Type: string

No Default

No Example

packages..components.library.postBuild

Type: null or string

Default: null

No Example

packages..components.library.postCheck

Type: null or string

Default: null

No Example

packages..components.library.postConfigure

Type: null or string

Default: null

No Example

packages..components.library.postHaddock

Type: null or string

Default: null

No Example

packages..components.library.postInstall

Type: null or string

Default: null

No Example

packages..components.library.postUnpack

Type: null or string

Default: null

No Example

packages..components.library.preBuild

Type: null or string

Default: null

No Example

packages..components.library.preCheck

Type: null or string

Default: null

No Example

packages..components.library.preConfigure

Type: null or string

Default: null

No Example

packages..components.library.preHaddock

Type: null or string

Default: null

No Example

packages..components.library.preInstall

Type: null or string

Default: null

No Example

packages..components.library.preUnpack

Type: null or strings concatenated with "\n"

Default: null

No Example

packages..components.library.profilingDetail

Type: null or string

Default: "default"

No Example

packages..components.library.setupBuildFlags

Type: list of string

Default: []

No Example

packages..components.library.setupHaddockFlags

Type: list of string

Default: []

No Example

packages..components.library.setupInstallFlags

Type: list of string

Default: []

No Example

packages..components.library.shellHook

Hook to run when entering a shell

Type: unspecified value

Default: ""

No Example

packages..components.library.testFlags

Type: list of string

Default: []

No Example

packages..components.library.testWrapper

A command to run for executing tests in checkPhase, which takes the original test command as its arguments.

Type: list of string

Default: []

Example:

"echo"

packages..components.library.writeHieFiles

Write component .hie files in the store in a hie output

Type: boolean

Default: false

No Example

packages..components.setup

Type: null or (submodule)

Default: {"asmSources":[],"cSources":[],"cmmSources":[],"cxxSources":[],"depends":[],"doExactConfig":false,"extraSrcFiles":["Setup.hs","Setup.lhs"],"frameworks":[],"hsSourceDirs":["setup-src"],"includeDirs":[],"jsSources":[],"libs":[],"platforms":null}

No Example

packages..components.setup.asmSources

Type: list of unspecified value

Default: []

No Example

packages..components.setup.build-tools

Type: list of unspecified value

Default: []

No Example

packages..components.setup.buildable

Type: boolean

Default: true

No Example

packages..components.setup.cSources

Type: list of unspecified value

Default: []

No Example

packages..components.setup.cmmSources

Type: list of unspecified value

Default: []

No Example

packages..components.setup.configureAllComponents

If set all the components in the package are configured (useful for cabal-doctest).

Type: boolean

Default: false

No Example

packages..components.setup.configureFlags

Type: list of string

Default: []

No Example

packages..components.setup.contentAddressed

Build content addressed derivation, requires Nix to have experimental feature ca-derivations enabled.

Type: boolean

Default: false

No Example

packages..components.setup.cxxSources

Type: list of unspecified value

Default: []

No Example

packages..components.setup.depends

Type: list of unspecified value

Default: []

No Example

packages..components.setup.doCheck

Type: boolean

Default: true

No Example

packages..components.setup.doCoverage

Enable production of test coverage reports.

Type: boolean

Default: false

No Example

packages..components.setup.doCrossCheck

Run doCheck also in cross compilation settings. This can be tricky as the test logic must know how to run the tests on the target.

Type: boolean

Default: false

No Example

packages..components.setup.doExactConfig

Type: boolean

Default: false

No Example

packages..components.setup.doHaddock

Enable building of the Haddock documentation from the annotated Haskell source code.

Type: boolean

Default: true

No Example

packages..components.setup.doHoogle

Also build a hoogle index.

Type: boolean

Default: true

No Example

packages..components.setup.doHyperlinkSource

Link documentation to the source code.

Type: boolean

Default: true

No Example

packages..components.setup.doQuickjump

Generate an index for interactive documentation navigation.

Type: boolean

Default: true

No Example

packages..components.setup.dontPatchELF

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

Type: boolean

Default: true

No Example

packages..components.setup.dontStrip

If set, libraries and executables are not stripped.

Type: boolean

Default: true

No Example

packages..components.setup.enableDeadCodeElimination

If set, enables split sections for link-time dead-code stripping. Only applies to Linux

Type: boolean

Default: true

No Example

packages..components.setup.enableLibraryProfiling

Type: boolean

Default: false

No Example

packages..components.setup.enableProfiling

Type: boolean

Default: false

No Example

packages..components.setup.enableSeparateDataOutput

Type: boolean

Default: true

No Example

packages..components.setup.enableShared

If set, enables building shared libraries.

Type: boolean

Default: true

No Example

packages..components.setup.enableStatic

If set, enables building static libraries and executables.

Type: boolean

Default: true

No Example

packages..components.setup.extraSrcFiles

Type: list of unspecified value

Default: []

No Example

packages..components.setup.frameworks

Type: list of package

Default: []

No Example

packages..components.setup.ghcOptions

Type: list of string

Default: []

No Example

packages..components.setup.hardeningDisable

Type: list of string

Default: []

No Example

packages..components.setup.hsSourceDirs

Type: list of unspecified value

Default: ["."]

No Example

packages..components.setup.includeDirs

Type: list of unspecified value

Default: []

No Example

packages..components.setup.includes

Type: list of unspecified value

Default: []

No Example

packages..components.setup.jsSources

Type: list of unspecified value

Default: []

No Example

packages..components.setup.keepSource

Keep component source in the store in a source output

Type: boolean

Default: false

No Example

packages..components.setup.libs

Type: list of (null or package or list of package)

Default: []

No Example

packages..components.setup.mainPath

Type: list of unspecified value

Default: []

No Example

packages..components.setup.modules

Type: list of unspecified value

Default: []

No Example

packages..components.setup.pkgconfig

Type: list of list of package

Default: []

No Example

packages..components.setup.planned

Set to true by plan-to-nix for any component that was included in the plan.json file.

Type: boolean

Default: false

No Example

packages..components.setup.platforms

Type: null or (list of unspecified value)

Default: null

No Example

packages..components.setup.plugins

Type: list of (submodule)

Default: []

No Example

packages..components.setup.plugins.*.args

Type: list of string

Default: []

No Example

packages..components.setup.plugins.*.library

Type: unspecified value

No Default

No Example

packages..components.setup.plugins.*.moduleName

Type: string

No Default

No Example

packages..components.setup.postBuild

Type: null or string

Default: null

No Example

packages..components.setup.postCheck

Type: null or string

Default: null

No Example

packages..components.setup.postConfigure

Type: null or string

Default: null

No Example

packages..components.setup.postHaddock

Type: null or string

Default: null

No Example

packages..components.setup.postInstall

Type: null or string

Default: null

No Example

packages..components.setup.postUnpack

Type: null or string

Default: null

No Example

packages..components.setup.preBuild

Type: null or string

Default: null

No Example

packages..components.setup.preCheck

Type: null or string

Default: null

No Example

packages..components.setup.preConfigure

Type: null or string

Default: null

No Example

packages..components.setup.preHaddock

Type: null or string

Default: null

No Example

packages..components.setup.preInstall

Type: null or string

Default: null

No Example

packages..components.setup.preUnpack

Type: null or strings concatenated with "\n"

Default: null

No Example

packages..components.setup.profilingDetail

Type: null or string

Default: "default"

No Example

packages..components.setup.setupBuildFlags

Type: list of string

Default: []

No Example

packages..components.setup.setupHaddockFlags

Type: list of string

Default: []

No Example

packages..components.setup.setupInstallFlags

Type: list of string

Default: []

No Example

packages..components.setup.shellHook

Hook to run when entering a shell

Type: unspecified value

Default: ""

No Example

packages..components.setup.testFlags

Type: list of string

Default: []

No Example

packages..components.setup.testWrapper

A command to run for executing tests in checkPhase, which takes the original test command as its arguments.

Type: list of string

Default: []

Example:

"echo"

packages..components.setup.writeHieFiles

Write component .hie files in the store in a hie output

Type: boolean

Default: false

No Example

packages..components.sublibs

Type: attribute set of (submodule)

Default: {}

No Example

packages..components.sublibs..asmSources

Type: list of unspecified value

Default: []

No Example

packages..components.sublibs..build-tools

Type: list of unspecified value

Default: []

No Example

packages..components.sublibs..buildable

Type: boolean

Default: true

No Example

packages..components.sublibs..cSources

Type: list of unspecified value

Default: []

No Example

packages..components.sublibs..cmmSources

Type: list of unspecified value

Default: []

No Example

packages..components.sublibs..configureAllComponents

If set all the components in the package are configured (useful for cabal-doctest).

Type: boolean

Default: false

No Example

packages..components.sublibs..configureFlags

Type: list of string

Default: []

No Example

packages..components.sublibs..contentAddressed

Build content addressed derivation, requires Nix to have experimental feature ca-derivations enabled.

Type: boolean

Default: false

No Example

packages..components.sublibs..cxxSources

Type: list of unspecified value

Default: []

No Example

packages..components.sublibs..depends

Type: list of unspecified value

Default: []

No Example

packages..components.sublibs..doCheck

Type: boolean

Default: true

No Example

packages..components.sublibs..doCoverage

Enable production of test coverage reports.

Type: boolean

Default: false

No Example

packages..components.sublibs..doCrossCheck

Run doCheck also in cross compilation settings. This can be tricky as the test logic must know how to run the tests on the target.

Type: boolean

Default: false

No Example

packages..components.sublibs..doExactConfig

Type: boolean

Default: false

No Example

packages..components.sublibs..doHaddock

Enable building of the Haddock documentation from the annotated Haskell source code.

Type: boolean

Default: true

No Example

packages..components.sublibs..doHoogle

Also build a hoogle index.

Type: boolean

Default: true

No Example

packages..components.sublibs..doHyperlinkSource

Link documentation to the source code.

Type: boolean

Default: true

No Example

packages..components.sublibs..doQuickjump

Generate an index for interactive documentation navigation.

Type: boolean

Default: true

No Example

packages..components.sublibs..dontPatchELF

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

Type: boolean

Default: true

No Example

packages..components.sublibs..dontStrip

If set, libraries and executables are not stripped.

Type: boolean

Default: true

No Example

packages..components.sublibs..enableDeadCodeElimination

If set, enables split sections for link-time dead-code stripping. Only applies to Linux

Type: boolean

Default: true

No Example

packages..components.sublibs..enableLibraryProfiling

Type: boolean

Default: false

No Example

packages..components.sublibs..enableProfiling

Type: boolean

Default: false

No Example

packages..components.sublibs..enableSeparateDataOutput

Type: boolean

Default: true

No Example

packages..components.sublibs..enableShared

If set, enables building shared libraries.

Type: boolean

Default: true

No Example

packages..components.sublibs..enableStatic

If set, enables building static libraries and executables.

Type: boolean

Default: true

No Example

packages..components.sublibs..extraSrcFiles

Type: list of unspecified value

Default: []

No Example

packages..components.sublibs..frameworks

Type: list of package

Default: []

No Example

packages..components.sublibs..ghcOptions

Type: list of string

Default: []

No Example

packages..components.sublibs..hardeningDisable

Type: list of string

Default: []

No Example

packages..components.sublibs..hsSourceDirs

Type: list of unspecified value

Default: ["."]

No Example

packages..components.sublibs..includeDirs

Type: list of unspecified value

Default: []

No Example

packages..components.sublibs..includes

Type: list of unspecified value

Default: []

No Example

packages..components.sublibs..jsSources

Type: list of unspecified value

Default: []

No Example

packages..components.sublibs..keepSource

Keep component source in the store in a source output

Type: boolean

Default: false

No Example

packages..components.sublibs..libs

Type: list of (null or package or list of package)

Default: []

No Example

packages..components.sublibs..mainPath

Type: list of unspecified value

Default: []

No Example

packages..components.sublibs..modules

Type: list of unspecified value

Default: []

No Example

packages..components.sublibs..pkgconfig

Type: list of list of package

Default: []

No Example

packages..components.sublibs..planned

Set to true by plan-to-nix for any component that was included in the plan.json file.

Type: boolean

Default: false

No Example

packages..components.sublibs..platforms

Type: null or (list of unspecified value)

Default: null

No Example

packages..components.sublibs..plugins

Type: list of (submodule)

Default: []

No Example

packages..components.sublibs..plugins.*.args

Type: list of string

Default: []

No Example

packages..components.sublibs..plugins.*.library

Type: unspecified value

No Default

No Example

packages..components.sublibs..plugins.*.moduleName

Type: string

No Default

No Example

packages..components.sublibs..postBuild

Type: null or string

Default: null

No Example

packages..components.sublibs..postCheck

Type: null or string

Default: null

No Example

packages..components.sublibs..postConfigure

Type: null or string

Default: null

No Example

packages..components.sublibs..postHaddock

Type: null or string

Default: null

No Example

packages..components.sublibs..postInstall

Type: null or string

Default: null

No Example

packages..components.sublibs..postUnpack

Type: null or string

Default: null

No Example

packages..components.sublibs..preBuild

Type: null or string

Default: null

No Example

packages..components.sublibs..preCheck

Type: null or string

Default: null

No Example

packages..components.sublibs..preConfigure

Type: null or string

Default: null

No Example

packages..components.sublibs..preHaddock

Type: null or string

Default: null

No Example

packages..components.sublibs..preInstall

Type: null or string

Default: null

No Example

packages..components.sublibs..preUnpack

Type: null or strings concatenated with "\n"

Default: null

No Example

packages..components.sublibs..profilingDetail

Type: null or string

Default: "default"

No Example

packages..components.sublibs..setupBuildFlags

Type: list of string

Default: []

No Example

packages..components.sublibs..setupHaddockFlags

Type: list of string

Default: []

No Example

packages..components.sublibs..setupInstallFlags

Type: list of string

Default: []

No Example

packages..components.sublibs..shellHook

Hook to run when entering a shell

Type: unspecified value

Default: ""

No Example

packages..components.sublibs..testFlags

Type: list of string

Default: []

No Example

packages..components.sublibs..testWrapper

A command to run for executing tests in checkPhase, which takes the original test command as its arguments.

Type: list of string

Default: []

Example:

"echo"

packages..components.sublibs..writeHieFiles

Write component .hie files in the store in a hie output

Type: boolean

Default: false

No Example

packages..components.tests

Type: attribute set of (submodule)

Default: {}

No Example

packages..components.tests..asmSources

Type: list of unspecified value

Default: []

No Example

packages..components.tests..build-tools

Type: list of unspecified value

Default: []

No Example

packages..components.tests..buildable

Type: boolean

Default: true

No Example

packages..components.tests..cSources

Type: list of unspecified value

Default: []

No Example

packages..components.tests..cmmSources

Type: list of unspecified value

Default: []

No Example

packages..components.tests..configureAllComponents

If set all the components in the package are configured (useful for cabal-doctest).

Type: boolean

Default: false

No Example

packages..components.tests..configureFlags

Type: list of string

Default: []

No Example

packages..components.tests..contentAddressed

Build content addressed derivation, requires Nix to have experimental feature ca-derivations enabled.

Type: boolean

Default: false

No Example

packages..components.tests..cxxSources

Type: list of unspecified value

Default: []

No Example

packages..components.tests..depends

Type: list of unspecified value

Default: []

No Example

packages..components.tests..doCheck

Type: boolean

Default: true

No Example

packages..components.tests..doCoverage

Enable production of test coverage reports.

Type: boolean

Default: false

No Example

packages..components.tests..doCrossCheck

Run doCheck also in cross compilation settings. This can be tricky as the test logic must know how to run the tests on the target.

Type: boolean

Default: false

No Example

packages..components.tests..doExactConfig

Type: boolean

Default: false

No Example

packages..components.tests..doHaddock

Enable building of the Haddock documentation from the annotated Haskell source code.

Type: boolean

Default: true

No Example

packages..components.tests..doHoogle

Also build a hoogle index.

Type: boolean

Default: true

No Example

packages..components.tests..doHyperlinkSource

Link documentation to the source code.

Type: boolean

Default: true

No Example

packages..components.tests..doQuickjump

Generate an index for interactive documentation navigation.

Type: boolean

Default: true

No Example

packages..components.tests..dontPatchELF

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

Type: boolean

Default: true

No Example

packages..components.tests..dontStrip

If set, libraries and executables are not stripped.

Type: boolean

Default: true

No Example

packages..components.tests..enableDeadCodeElimination

If set, enables split sections for link-time dead-code stripping. Only applies to Linux

Type: boolean

Default: true

No Example

packages..components.tests..enableLibraryProfiling

Type: boolean

Default: false

No Example

packages..components.tests..enableProfiling

Type: boolean

Default: false

No Example

packages..components.tests..enableSeparateDataOutput

Type: boolean

Default: true

No Example

packages..components.tests..enableShared

If set, enables building shared libraries.

Type: boolean

Default: true

No Example

packages..components.tests..enableStatic

If set, enables building static libraries and executables.

Type: boolean

Default: true

No Example

packages..components.tests..extraSrcFiles

Type: list of unspecified value

Default: []

No Example

packages..components.tests..frameworks

Type: list of package

Default: []

No Example

packages..components.tests..ghcOptions

Type: list of string

Default: []

No Example

packages..components.tests..hardeningDisable

Type: list of string

Default: []

No Example

packages..components.tests..hsSourceDirs

Type: list of unspecified value

Default: ["."]

No Example

packages..components.tests..includeDirs

Type: list of unspecified value

Default: []

No Example

packages..components.tests..includes

Type: list of unspecified value

Default: []

No Example

packages..components.tests..jsSources

Type: list of unspecified value

Default: []

No Example

packages..components.tests..keepSource

Keep component source in the store in a source output

Type: boolean

Default: false

No Example

packages..components.tests..libs

Type: list of (null or package or list of package)

Default: []

No Example

packages..components.tests..mainPath

Type: list of unspecified value

Default: []

No Example

packages..components.tests..modules

Type: list of unspecified value

Default: []

No Example

packages..components.tests..pkgconfig

Type: list of list of package

Default: []

No Example

packages..components.tests..planned

Set to true by plan-to-nix for any component that was included in the plan.json file.

Type: boolean

Default: false

No Example

packages..components.tests..platforms

Type: null or (list of unspecified value)

Default: null

No Example

packages..components.tests..plugins

Type: list of (submodule)

Default: []

No Example

packages..components.tests..plugins.*.args

Type: list of string

Default: []

No Example

packages..components.tests..plugins.*.library

Type: unspecified value

No Default

No Example

packages..components.tests..plugins.*.moduleName

Type: string

No Default

No Example

packages..components.tests..postBuild

Type: null or string

Default: null

No Example

packages..components.tests..postCheck

Type: null or string

Default: null

No Example

packages..components.tests..postConfigure

Type: null or string

Default: null

No Example

packages..components.tests..postHaddock

Type: null or string

Default: null

No Example

packages..components.tests..postInstall

Type: null or string

Default: null

No Example

packages..components.tests..postUnpack

Type: null or string

Default: null

No Example

packages..components.tests..preBuild

Type: null or string

Default: null

No Example

packages..components.tests..preCheck

Type: null or string

Default: null

No Example

packages..components.tests..preConfigure

Type: null or string

Default: null

No Example

packages..components.tests..preHaddock

Type: null or string

Default: null

No Example

packages..components.tests..preInstall

Type: null or string

Default: null

No Example

packages..components.tests..preUnpack

Type: null or strings concatenated with "\n"

Default: null

No Example

packages..components.tests..profilingDetail

Type: null or string

Default: "default"

No Example

packages..components.tests..setupBuildFlags

Type: list of string

Default: []

No Example

packages..components.tests..setupHaddockFlags

Type: list of string

Default: []

No Example

packages..components.tests..setupInstallFlags

Type: list of string

Default: []

No Example

packages..components.tests..shellHook

Hook to run when entering a shell

Type: unspecified value

Default: ""

No Example

packages..components.tests..testFlags

Type: list of string

Default: []

No Example

packages..components.tests..testWrapper

A command to run for executing tests in checkPhase, which takes the original test command as its arguments.

Type: list of string

Default: []

Example:

"echo"

packages..components.tests..writeHieFiles

Write component .hie files in the store in a hie output

Type: boolean

Default: false

No Example

packages..configureAllComponents

If set all the components in the package are configured (useful for cabal-doctest).

Type: boolean

Default: false

No Example

packages..configureFlags

Type: list of string

Default: []

No Example

packages..contentAddressed

Build content addressed derivation, requires Nix to have experimental feature ca-derivations enabled.

Type: boolean

Default: false

No Example

packages..doCheck

Type: boolean

Default: true

No Example

packages..doCoverage

Enable production of test coverage reports.

Type: boolean

Default: false

No Example

packages..doCrossCheck

Run doCheck also in cross compilation settings. This can be tricky as the test logic must know how to run the tests on the target.

Type: boolean

Default: false

No Example

packages..doExactConfig

Type: boolean

Default: false

No Example

packages..doHaddock

Enable building of the Haddock documentation from the annotated Haskell source code.

Type: boolean

Default: true

No Example

packages..doHoogle

Also build a hoogle index.

Type: boolean

Default: true

No Example

packages..doHyperlinkSource

Link documentation to the source code.

Type: boolean

Default: true

No Example

packages..doQuickjump

Generate an index for interactive documentation navigation.

Type: boolean

Default: true

No Example

packages..dontPatchELF

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

Type: boolean

Default: true

No Example

packages..dontStrip

If set, libraries and executables are not stripped.

Type: boolean

Default: true

No Example

packages..enableDeadCodeElimination

If set, enables split sections for link-time dead-code stripping. Only applies to Linux

Type: boolean

Default: true

No Example

packages..enableLibraryProfiling

Type: boolean

Default: false

No Example

packages..enableProfiling

Type: boolean

Default: false

No Example

packages..enableSeparateDataOutput

Type: boolean

Default: true

No Example

packages..enableShared

If set, enables building shared libraries.

Type: boolean

Default: true

No Example

packages..enableStatic

If set, enables building static libraries and executables.

Type: boolean

Default: true

No Example

packages..flags

Type: attribute set of boolean

No Default

No Example

packages..ghcOptions

Type: list of string

Default: []

No Example

packages..hardeningDisable

Type: list of string

Default: []

No Example

packages..keepSource

Keep component source in the store in a source output

Type: boolean

Default: false

No Example

packages..name

Type: string

Default: "${config.package.identifier.name}-${config.package.identifier.version}"

No Example

packages..package.author

Type: string

No Default

No Example

packages..package.buildType

Type: string

No Default

No Example

packages..package.buildable

Type: boolean

Default: true

No Example

packages..package.cleanHpack

Type: boolean

Default: false

No Example

packages..package.copyright

Type: string

No Default

No Example

packages..package.dataDir

Type: string

Default: ""

No Example

packages..package.dataFiles

Type: list of unspecified value

Default: []

No Example

packages..package.description

Type: string

No Default

No Example

packages..package.detailLevel

Type: string

Default: "MinimalDetails"

No Example

packages..package.extraDocFiles

Type: list of unspecified value

Default: []

No Example

packages..package.extraSrcFiles

Type: list of unspecified value

Default: []

No Example

packages..package.extraTmpFiles

Type: list of unspecified value

Default: []

No Example

packages..package.homepage

Type: string

No Default

No Example

packages..package.identifier.name

Type: string

No Default

No Example

packages..package.identifier.version

Type: string

No Default

No Example

packages..package.isLocal

Type: boolean

Default: false

No Example

packages..package.isProject

Type: boolean

Default: false

No Example

packages..package.license

Type: string

No Default

No Example

packages..package.licenseFiles

Type: list of unspecified value

Default: []

No Example

packages..package.maintainer

Type: string

No Default

No Example

packages..package.setup-depends

Type: list of unspecified value

Default: []

No Example

packages..package.specVersion

Type: string

No Default

No Example

packages..package.synopsis

Type: string

No Default

No Example

packages..package.url

Type: string

No Default

No Example

packages..patches

Type: list of (unspecified value or (path))

Default: []

No Example

packages..planned

Set to true by plan-to-nix for any component that was included in the plan.json file.

Type: boolean

Default: false

No Example

packages..postBuild

Type: null or string

Default: null

No Example

packages..postCheck

Type: null or string

Default: null

No Example

packages..postConfigure

Type: null or string

Default: null

No Example

packages..postHaddock

Type: null or string

Default: null

No Example

packages..postInstall

Type: null or string

Default: null

No Example

packages..postUnpack

Type: null or string

Default: null

No Example

packages..preBuild

Type: null or string

Default: null

No Example

packages..preCheck

Type: null or string

Default: null

No Example

packages..preConfigure

Type: null or string

Default: null

No Example

packages..preHaddock

Type: null or string

Default: null

No Example

packages..preInstall

Type: null or string

Default: null

No Example

packages..preUnpack

Type: null or strings concatenated with "\n"

Default: null

No Example

packages..profilingDetail

Type: null or string

Default: "default"

No Example

packages..revision

Type: null or signed integer

Default: null

No Example

packages..revisionSha256

Type: null or string

Default: null

No Example

packages..setupBuildFlags

Type: list of string

Default: []

No Example

packages..setupHaddockFlags

Type: list of string

Default: []

No Example

packages..setupInstallFlags

Type: list of string

Default: []

No Example

packages..sha256

Type: null or string

Default: null

No Example

packages..shellHook

Hook to run when entering a shell

Type: unspecified value

Default: ""

No Example

packages..src

Type: (path) or package

Default: "pkgs.fetchurl { url = "mirror://hackage/${config.name}.tar.gz"; inherit (config) sha256; };"

No Example

packages..testFlags

Type: list of string

Default: []

No Example

packages..testWrapper

A command to run for executing tests in checkPhase, which takes the original test command as its arguments.

Type: list of string

Default: []

Example:

"echo"

packages..writeHieFiles

Write component .hie files in the store in a hie output

Type: boolean

Default: false

No Example

planned

Set to true by plan-to-nix for any component that was included in the plan.json file.

Type: boolean

Default: false

No Example

postBuild

Type: null or string

Default: null

No Example

postCheck

Type: null or string

Default: null

No Example

postConfigure

Type: null or string

Default: null

No Example

postHaddock

Type: null or string

Default: null

No Example

postInstall

Type: null or string

Default: null

No Example

postUnpack

Type: null or string

Default: null

No Example

preBuild

Type: null or string

Default: null

No Example

preCheck

Type: null or string

Default: null

No Example

preConfigure

Type: null or string

Default: null

No Example

preHaddock

Type: null or string

Default: null

No Example

preInstall

Type: null or string

Default: null

No Example

preUnpack

Type: null or strings concatenated with "\n"

Default: null

No Example

profilingDetail

Type: null or string

Default: "default"

No Example

reinstallableLibGhc

Is lib:ghc reinstallable?

Type: boolean

Default: true

No Example

setup-depends

pkgs to globally provide to Setup.hs builds

Type: list of unspecified value

Default: []

No Example

setupBuildFlags

Type: list of string

Default: []

No Example

setupHaddockFlags

Type: list of string

Default: []

No Example

setupInstallFlags

Type: list of string

Default: []

No Example

shellHook

Hook to run when entering a shell

Type: unspecified value

Default: ""

No Example

testFlags

Type: list of string

Default: []

No Example

testWrapper

A command to run for executing tests in checkPhase, which takes the original test command as its arguments.

Type: list of string

Default: []

Example:

"echo"

writeHieFiles

Write component .hie files in the store in a hie output

Type: boolean

Default: false

No Example

Troubleshooting

Issues with building and garbage-collection

Why am I building GHC?

It's easier to list the reverse: when will you not build GHC?

  • You have configured the binary cache correctly.
  • You are using one of the GHC versions which we support.
  • You are using one of the nixpkgs versions used by our CI (you can access the sources for these through haskell.nix.

If you think you are doing all of these and you still find you're building GHC, drop us a line.

Why am I building lots of Haskell packages?

We don't generally cache much of Hackage (there's a lot of it!), except for the parts which are used by our tests. So this is expected, unfortunately.

How do I prevent the evaluation-time dependencies of my project from being garbage-collected?

The haskell-nix.roots "ghc884" should include all the evaluation-time dependencies and the main build time dependencies of a project using ghc 8.8.4. So you can add that to the relevant GC root. In practice, if you're using a CI system like Hydra/Hercules, this means adding it to a job in release.nix/ci.nix.

General troubleshooting when using cabalProject/stackProject/project

Does the cabal/stack build work?

In haskell.nix, we strive to take the build configuration from the cabal/stack configuration files. So if you have a problem with your cabal/stack configuration, it is likely that you will have a problem with the haskell.nix build too.

So the first thing to do is make sure that the build works with cabal or stack as normal. If it does work, then the haskell.nix one should as well. If, on the other hand, there is a failure, the cabal or stack build is usually easier to debug (or at least it is no longer a haskell.nix problem).

Is the haskell.nix configuration completely in line with the cabal/stack configuration?

The haskell.nix configuration can come apart from the cabal/stack configuration in a number of ways:

Compiler version

(Cabal users only. For stack users this comes from the snapshot, so stack and haskell.nix will agree.)

The compiler version used by haskell.nix is selected by the compiler-nix-name argument; or if you do not specify it, by some default version (we recommend specifying it!). Cabal does not provide an easy way to pin a version of the compiler (with-compiler lets you pick a particular executable, which is nearly but not quite what we want). Hence, the two can come apart.

Make sure you are using the same compiler for the cabal build as for the haskell.nix build.

Hackage index state

(Cabal users only. For stack users, package versions come from the snapshot, so stack and haskell.nix will agree.)

Cabal has the concept of the Hackage "index state". This is a timestamp, and it tells Cabal to behave "as if" it was seeing Hackage at that point in time. Pinning it is generally good for reproducibility regardless of whether you use haskell.nix (you can do so in cabal.project).

If you do not set an index-state in cabal.project, then Cabal will use the latest one based on when you last called cabal update, and haskell.nix will use the latest one it knows about from hackage.nix. These may not be the same! So if you use haskell.nix we strongly recommend pinning the index-state.

Nix-only configuration options

You can set configuration options in your Nix code that are not present in the cabal/stack configuration. For example, you might enable profiling.

Where possible, try to do the configuration in your cabal/stack configuration, e.g. setting profiling: true in cabal.project. This will ensure that the two builds agree.

If you want or need to set some of them in Nix, try bringing the two into sync temporarily for troubleshooting.

Other specific issues

Why does the build complain about some files being missing?

Sometimes your build works fine outside haskell.nix, but inside the haskell.nix build, cabal complains that some file is missing. What is going on?

The answer is that haskell.nix thoroughly cleans the source by following what is mentioned as required in the cabal file. So we only include Haskell sources if they appear in a hs-source-dirs somewhere; and we only include non-Haskell files if they are included in extra-source-files or similar.

This is good practice anyway: if you do not include such files in extra-source-files then they will not be included in cabal sdist, which will cause problems if you ever upload your package to Hackage. But haskell.nix is very picky about it.

Why does my executable depend on GHC/GCC?

You may want to set the dontStrip option to false (see https://github.com/input-output-hk/haskell.nix/issues/829). This is not set by default because it can occasionally cause breakage.

Templates / Abstraction

IOHK's nix tooling

iohk-nix

iohk-nix is IOHK's shared nix library. It provides some templates to make working with haskell.nix trivial but is non-essential to use haskell.nix infrastructure.

lib.nix

let
  # iohk-nix can be overridden for debugging purposes by setting
  # NIX_PATH=iohk_nix=/path/to/iohk-nix
  iohkNix = import (
    let try = builtins.tryEval <iohk_nix>;
    in if try.success
    then builtins.trace "using host <iohk_nix>" try.value
    else
      let
        spec = builtins.fromJSON (builtins.readFile ./iohk-nix.json);
      in builtins.fetchTarball {
        url = "${spec.url}/archive/${spec.rev}.tar.gz";
        inherit (spec) sha256;
      }) {};

  pkgs = iohkNix.pkgs;
  lib = pkgs.lib;
in lib // { inherit iohkNix pkgs; inherit (iohkNix) nix-tools; }

iohk-nix.json

{
    "url": "https://github.com/input-output-hk/iohk-nix",
    "rev": "c92f0119ef5814b0ed1f445c2fdcf8894e326294",
    "sha256": "05r90x6x3yp1nb66rkc4n0i8q15c634rrdsr2zvb118s3sdcmmrm",
    "fetchSubmodules": false
}

nix/pkgs.nix

{ pkgs ? import <nixpkgs> {}
, iohk-extras ? {}
, iohk-module ? {}
, haskell
, hackage
, stackage
, ...
}:
let
  # our packages
  stack-pkgs = import ./.stack-pkgs.nix;

  # Build the packageset with module support.
  # We can essentially override anything in the modules
  # section.
  #
  #  packages.cbors.patches = [ ./one.patch ];
  #  packages.cbors.flags.optimize-gmp = false;
  #
  compiler = (stack-pkgs.extras hackage).compiler.nix-name;
  pkgSet = haskell.mkNewPkgSet {
    inherit pkgs;
    pkg-def = stackage.${stack-pkgs.resolver};
    # These extras allow extension or restriction of the set of
    # packages we are interested in. By using the stack-pkgs.extras
    # we restrict our package set to the ones provided in stack.yaml.
    pkg-def-extras = [
      stack-pkgs.extras
      iohk-extras.${compiler}
    ];
    # package customizations
    modules = [
      # This module will ensure that we get the necessary
      # patches ontop of GHC packages that for which the
      # ones that GHC ships are not identical to the ones
      # we find on hackage. These patches will make sure
      # they are identical by augmenting the packages on
      # hackage to match those that ship with ghc.
      haskell.ghcHackagePatches.${compiler}

      # the iohk-module will supply us with the necessary
      # cross compilation plumbing to make Template Haskell
      # work when cross compiling.  For now we need to
      # list the packages that require template haskell
      # explicity here.
      iohk-module
    ];
  };
in
  pkgSet.config.hsPkgs // { _config = pkgSet.config; }

default.nix

let
  localLib = import ./lib.nix;
in
# This file needs to export a function that takes
# the arguments it is passed and forwards them to
# the default-nix template from iohk-nix. This is
# important so that the release.nix file can properly
# parameterize this file when targetting different
# hosts.
{ ... }@args:
# We will instantiate the defaul-nix template with the
# nix/pkgs.nix file...
localLib.nix-tools.default-nix ./nix/pkgs.nix args
# ... and add a few custom packages as well.
// { }

Dev Notes

Developer Architecture Overview

This shall give a sufficiently good overview over the haskell.nix ideas, such that a new developer can navigate around without too much trouble.

Packages

haskell.nix is centered around packages (haskell package descriptions as nix-expressions). These are generated by cabal-to-nix from the nix-tools package. stack-to-nix and plan-to-nix will delegate the transformation of cabal packages to nix expressions to the same code that cabal-to-nix uses.

These packages will look similar to the following:

{ system, compiler, flags, pkgs, hsPkgs, pkgconfPkgs, ... }:
{
  flags = {};
  package = { ... };
  components = {
    "library" = { depends = [ ... ]; };
    exes = { "..." = { depends = [ ... ]; }; ... };
    sublibs = { "..." = { depends = [ ... ]; }; ... };
    tests = { "..." = { depends = [ ... ]; }; ... };
    benchmarks = { "..." = { depends = [ ... ]; }; ... };
  };
};

The exact specification can be found in modules/package.nix.

Plans

Packages (unless specified directly in the packages attribute of the module) usually come from a plan. A plan is either a Stackage snapshot (nightly or LTS) or a build plan as produced by cabal.

Plan files usually look like the following:

hackage:
{
  packages = {
    "$pkg".revision = hackage.$pkg.$version.revisions.default;
    "$pkg".flags = { flag1 = true; flag2 = false; ... };
	...
  };
  compiler = {
    version = "8.4.4";
      nix-name = "ghc844";
      packages = {
        "binary" = "0.8.5.1";
	...
      };
   };
}

This provides enough information about the compiler, what packages the compiler ships with and the packages we want to use in our plan.

This revision and flag information will be inlined into a list of packages in config.packages in modules/plan.nix. Thus config.packages will only contains packages as described in the previous section.

Package Sets (of derivations)

We finally tie this all together in package-set.nix where we use modules/component-driver.nix to produce the derivations for each packages component to produce the final config.hsPkgs value.

There is also a modules/compat-driver.nix that should produce the same packageset to be used with the stock haskell infrastructure in nixpkgs (This has undergone substantially less testing).

Component builder

To prevent depending on multiple instances of the same libraries, the component builder will try to build every package from scratch and rely as little as possible on packages that are shipped with the GHC distribution. The exceptions are packages that are known to not be reinstallable. See config.nonReinstallablePkgs.

The component builder can be found in modules/component-driver.nix and builder/default.nix. The component-driver will ensure that we do not try to rebuild non-reinstallable packages, and call the builder/default.nix on each package in config.packages to produce config.hsPkgs.

Installing nix-tools

To build the latest nix-tools and store the result at ./nt, run:

nix build -f https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz pkgs.haskell-nix.nix-tools.ghc884 --out-link nt

If you would like to then install nix-tools into your profile, run:

nix-env -i ./nt

Optional: Installing via Haskell.nix source

The Haskell.nix and nix-tools source will be useful if you would like to contribute improvements, or read the source code to fully understand something that the documentation doesn't cover.

git clone https://github.com/input-output-hk/nix-tools
git clone https://github.com/input-output-hk/haskell.nix
cd haskell.nix
nix build -f . pkgs.haskell-nix.nix-tools.ghc884 --arg sourcesOverride '{ nix-tools = ../nix-tools; }' --out-link nt

How to update nix-tools

  1. Use niv to update the sources.json:

    nix flake lock --update-input nix-tools
    
  2. If nix-tools.cabal or plan-to-nix have changed, check the materialized files for each of the compiler nix name in ls -d materialized/ghc*/nix-tools with:

    nix-build scripts/check-compiler-materialization --argstr compiler-nix-name ghc884
    

Manually generating Nix expressions

We believe that imports from derivations (IFDs) provide tremendous value in nix and the aversion towards them stems mostly from poor tooling and ci support for them. We do not believe that poor tooling or ci support should cripple nix capability of abstraction. Hence haskell.nix makes excessive use of IFDs.

We do note however that there are users who prefer to have IFD-free expressions. For this group of users we detail how to expand the IFD dependent high level functions into their IFD free building blocks.

The general structure will be the same, independent of the use of Stack or Cabal.

Let us assume for now that we have already generated a pkgs.nix expression (see the links bellow). The following file then produces a package set:

# default.nix
let
  # Import the Haskell.nix library,
  pkgs = import <nixpkgs> (import (builtins.fetchTarball "https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz") {}).nixpkgsArgs;

  # Import the file you will create in the stack-to-nix or cabal-to-nix step.
  my-pkgs = import ./pkgs.nix;

  # Stack projects use this:
  # pkgSet = pkgs.haskell-nix.mkStackPkgSet {
  #   stack-pkgs = my-pkgs;
  #   pkg-def-extras = [
  #     # these extras will provide additional packages
  #     # ontop of the package set.  E.g. extra-deps
  #     # for stack packages. or local packages for
  #     # cabal.projects
  #   ];
  #   modules = [
  #     # specific package overrides would go here
  #     # example:
  #     #  packages.cbors.package.ghcOptions = "-Werror";
  #     #  packages.cbors.patches = [ ./one.patch ];
  #     #  packages.cbors.flags.optimize-gmp = false;
  #     # It may be better to set flags in stack.yaml instead
  #     # (`stack-to-nix` will include them as defaults).
  #   ];
  # };

  # Cabal projects use this:
  pkgSet = pkgs.haskell-nix.mkCabalProjectPkgSet {
    plan-pkgs = my-pkgs;
    pkg-def-extras = [];
    modules = [
      # specific package overrides would go here
      # example:
      #  packages.cbors.package.ghcOptions = "-Werror";
      #  packages.cbors.patches = [ ./one.patch ];
      #  packages.cbors.flags.optimize-gmp = false;
      # It may be better to set flags in `cabal.project` instead
      # (`plan-to-nix` will include them as defaults).
    ];
  };

in pkgSet.config.hsPkgs // { _config = pkgSet.config; }

With this setup you can then start building the components of interest:

nix build -f default.nix $pkg.components.library

to build the library for $pkg or

nix build -f default.nix $pkg.components.exes.$exe

to build a specific executable. The same holds for test suites and benchmarks.

Using Stack

With nix-tools installed, we can simply run the following command on a stack project:

stack-to-nix --output . --stack-yaml stack.yaml

This will produce a pkgs.nix file that looks like the following:

{
  resolver = "lts-12.17";
  extras = hackage:
    {
      packages = {
        "o-clock" = hackage.o-clock."0.1.1".revisions.default;
        ...
      } // {
        my-package = ./my-package.nix;
        ...
      };
    };
}

This file contains the stackage resolver, as well as set of extra packages. The extras specifies which extra-deps (here: o-clock-0.1.1) we wanted to add over the stackage snapshot, and what local packages we want (here: my-package).

Using Cabal

Generating plan.json

To get a plan, you need Cabal and GHC. See the How to install a compiler section of the Nixpkgs Manual for information about how to choose a specific compiler version.

Note: Cabal version

The minimum Cabal version is 2.4. This version is available in the NixOS 19.03 release.

For this example, we will run a nix-shell with the default GHC version for Nixpkgs.

nix-shell -p haskellPackages.cabal-install haskellPackages.ghc \
    --run "cabal new-configure"

If all goes well, you should now have the file dist-newstyle/cache/plan.json.

Tip: Specifying the GHC version

To use a specific compiler version, replace haskellPackages.ghc with something like haskell-nix.compiler.ghc865. The given compiler must exist in your Nixpkgs version, of course. See also the Nixpkgs Manual.

Using plan-to-nix

With nix-tools installed, we can then run the following command on a Cabal project and its build plan. Omit the --cabal-project option if you don't have a project file.

# convert the plan.json file into a pkgs.nix file
plan-to-nix --output . \
    --plan-json dist-newstyle/cache/plan.json
    --cabal-project cabal.project

This will produce a pkgs.nix file that looks like the following:

{
  pkgs = hackage:
    {
      packages = {
        "o-clock" = hackage.o-clock."0.1.1".revisions.default;
        ...
      };
      compiler = { ... };
    };

  extras = hackage:
    { packages = { my-package = ./.plan.nix/my-package.nix; }; };
}

It has converted Cabal's build plan into a Nix expression that selects dependencies from hackage.nix. All local packages in the project are generated with cabal-to-nix and added to the package set description.

Updating Hackage and Stackage Nix expressions

The hackage.nix and stackage.nix repos and corresponding files hackage-src.json and stackage-src.json will be regularly and automatically updated using scripts in this repo.

To run the updater scripts manually, use:

nix-build build.nix -A maintainer-scripts.update-hackage -o update-hackage.sh
./update-hackage.sh

nix-build build.nix -A maintainer-scripts.update-stackage -o update-stackage.sh
./update-stackage.sh

The scripts will clone the repo, generate the latest data, then attempt to push back to the repo and update the source JSON file.

Haskell.nix Nixpkgs Pin

Haskell.nix contains several Nixpkgs pins imanaged by niv in nix/sources.json.

These are used in testing various versions of nixpkgs.

To use haskell.nix the config and overlays need to be applied to Nixpkgs. Users should probably pin a suitable version of nixpkgs, although things might not work for them if their Nixpkgs version is too different.

We aim to keep this pin somewhere on a channel of the Nixpkgs latest stable release. That is currently 20.09.

We also execute tests on MacOS (darwin). The darwin channel is usually behind the NixOS channel. So we follow the nixpkgs-20.09-darwin channel.

ghcWithPackages wrapper removal

The current Nixpkgs Haskell infrastructure and haskell.nix both provide a ghcWithPackages derivation which contains shell script wrappers that wrap ghc and ghc-pkg.

In the Nixpkgs Haskell infrastructure, the wrapper scripts are used for building Haskell packages. However, in haskell.nix, the wrappers are only used for development environments.

The wrapper scripts provide a ghc command that "knows" about the package set and has all Haskell package dependencies available to it.

We would like to remove the wrapper scripts, but it's currently not possible to configure all build tools using environment variables alone.

Plain ghc

When using ghc or ghci by itself, the GHC_ENVIRONMENT variable can point to a configuration file containing an exact package set. This works quite well.

ghc-pkg

The package tool ghc-pkg does not recognize GHC_ENVIRONMENT, but does recognize a GHC_PACKAGE_PATH pointing to a package.conf.d.

This works well. However, the cabal command will refuse to start if GHC_PACKAGE_PATH is set.

Setup.hs

When invoking Setup.hs configure, the package database is provided with the --package-db argument and exact dependencies in the package set can be provided as --dependency arguments.

The haskell.nix component builder uses Setup.hs with these command-line options to build Haskell packages.

cabal new-build

Cabal-install will observe the CABAL_CONFIG environment variable, which points to a cabal config file. This config file can provide a package-db value, but it can't specify exact versions of packages.

Cabal is designed to solve dependencies, not simply take the package set which is given to it.

Therefore, cabal does not use GHC_ENVIRONMENT, but instead creates its own environment file. It will not accept --dependency arguments.

As far as I know, the best way to force cabal to take a pre-computed package set is to use a new-freeze file. However there is no environment variable (or config file entry) which can specify a path to a freeze file.

Specifying a package-db path in the cabal config file is not enough for it to successfully resolve dependencies.

As mentioned before, cabal does not work when GHC_PACKAGE_PATH is set. The best way to work around this is to wrap ghc and ghc-pkg in shell scripts.

Haskell infrastructure test cases

To build the test cases, run from the test directory:

nix-build --no-out-link default.nix

To run all tests (includes impure tests), use the script:

./tests.sh

Generated code

If you change the test Cabal files or need to regenerate the code with nix-tools, then see regen.nix. Run it like this:

$(nix-build --no-out-link regen.nix)

Adding a new GHC version to haskell.nix

Update overlays/bootstrap.nix

Each ghc version is defined in this file. Duplicate one of the existing ghc version definitions and replace the version numbers. Make sure you update the spec.sha256 or the other versions source will be used. Check the LLVM version that should be used in the ghc wiki.

Update the list of cached GHC versions in ci.nix

Update supported ghc versions document

Add the materialized files

In the haskell.nix repo run:

mkdir materialized/ghc884
nix-build scripts/check-compiler-materialization --argstr compiler-nix-name ghc884

The nix-build command will fail with something like:

Materialized nix used for dummy-data-x86_64-unknown-linux-musl-ghc-8.10.1 incorrect. To fix run: /nix/store/wnwpyrhv4nxgyljz3f20gdpspjxvm7h4-updateMaterialized

Run the updateMaterialized script and repeat the nix-build until it no longer fails. If the failure is not a problem with materialization and no updateMaterialized script is provided then you may need to fix the failure another way or (if it only relates to one of the cross compilers) modify scripts/check-compiler-materialization/default.nix so that it skips that compiler.

Developer Coverage Overview

Building

The implementation of coverage starts with the "doCoverage" flag on the builder in comp-builder.nix. The doCoverage flag enables and disables the Cabal coverage flag and copies any generated coverage data to "$out/share/hpc".

Mix and tix files

The coverage information for any derivation consists of "mix" and "tix" files.

Mix files record static information about a source file and are generated at build time. They primarily contain a path to the source file and information about expressions and regions of the source file, which are later referenced by tix files.

Tix files contain dynamic information about a test run, recording when a portion of a source file is touched by a test. These are generated when the test is run.

Multiple local packages

In the context of multiple local packages, there are a few types of coverage we might be interested in:

  • How well does the tests for this package cover the package library?
  • How well does the tests for this package cover the libraries of other packages in this project?
  • Both of the above.

To facilitate expressing any of these classifications of coverage, the lib/cover.nix function provides the mixLibraries argument. If you're just interested in how the tests cover the package library, you provide that library as an argument to mixLibraries. If you're interested in how the tests also cover other local packages in the project, you can also provide those libraries as arguments to mixLibraries.

The projectCoverageReport and coverageReport attributes that are provided by default on projects and packages respectively provide coverage information for all local packages in the project. This is to mimic the behaviour of Stack, which seems to be the expectation of most people. Of course, you can use the projectCoverageReport and coverageReport functions to construct your own custom coverage reports (as detailed in the coverage tutorial).

Coverage reports

Package reports

The coverage information generated will look something like this:

/nix/store/...-my-project-0.1.0.0-coverage-report/
└── share
    └── hpc
        └── vanilla
            ├── html
            │   └── my-library-0.1.0.0
            │       ├── my-library-0.1.0.0-48EVZBwW9Kj29VTaRMhBDf
            │       │   ├── My.Lib.Config.hs.html
            │       │   ├── My.Lib.Types.hs.html
            │       │   └── My.Lib.Util.hs.html
            │       ├── hpc_index_alt.html
            │       ├── hpc_index_exp.html
            │       ├── hpc_index_fun.html
            │       └── hpc_index.html
            ├── mix
            │   └── my-library-0.1.0.0
            │       └── my-library-0.1.0.0-48EVZBwW9Kj29VTaRMhBDf
            │           ├── My.Lib.Config.mix
            │           ├── My.Lib.Types.mix
            │           └── My.Lib.Util.mix
            └── tix
                └── my-library-0.1.0.0
                    ├── my-library-0.1.0.0.tix
                    ├── my-test-1
                    │   └── my-test-1.tix
                    └── unit-test
                        └── unit-test.tix
  • The mix files are copied verbatim from the library built with coverage.
  • The tix files for each test are copied from the check run verbatim and are output to ".../tix///.tix".
  • The tix files for each library are generated by summing the tix files for each test, but excluding any test modules. This tix file is output to ".../tix//.tix".
    • Test modules are determined by inspecting the plan for the project (i.e. for the project "my-project" and test-suite "my-test-1", the test modules are read from: my-project.checks.my-test-1.config.modules)
  • The hpc HTML reports for each library are generated from their respective tix files (i.e. the share/hpc/vanilla/html/my-library-0.1.0.0 report is generated from the share/hpc/vanilla/tix/my-library-0.1.0.0/my-library-0.1.0.0.tix file)

Project-wide reports

The coverage information for an entire project will look something like this:

/nix/store/...-coverage-report
└── share
    └── hpc
        └── vanilla
            ├── html
            │   ├── index.html
            │   ├── all
            │   │   ├── my-library-0.1.0.0-ERSaOroBZhe9awsoBkhmcV
            │   │   │   ├── My.Lib.Config.hs.html
            │   │   │   ├── My.Lib.Types.hs.html
            │   │   │   └── My.Lib.Util.hs.html
            │   │   ├── other-library-0.1.0.0-48EVZBwW9Kj29VTaRMhBDf
            │   │   │   ├── Other.Lib.A.hs.html
            │   │   │   └── Other.Lib.B.hs.html
            │   │   ├── hpc_index_alt.html
            │   │   ├── hpc_index_exp.html
            │   │   ├── hpc_index_fun.html
            │   │   └── hpc_index.html
            │   ├── my-library-0.1.0.0
            │   │   ├── my-library-0.1.0.0-ERSaOroBZhe9awsoBkhmcV
            │   │   │   ├── My.Lib.Config.hs.html
            │   │   │   ├── My.Lib.Types.hs.html
            │   │   │   └── My.Lib.Util.hs.html
            │   │   ├── hpc_index_alt.html
            │   │   ├── hpc_index_exp.html
            │   │   ├── hpc_index_fun.html
            │   │   └── hpc_index.html
            │   └── other-libray-0.1.0.0
            │       ├── other-library-0.1.0.0-48EVZBwW9Kj29VTaRMhBDf
            │       │   ├── Other.Lib.A.hs.html
            │       │   └── Other.Lib.B.hs.html
            │       ├── hpc_index_alt.html
            │       ├── hpc_index_exp.html
            │       ├── hpc_index_fun.html
            │       └── hpc_index.html
            ├── mix
            │   ├── my-library-0.1.0.0-ERSaOroBZhe9awsoBkhmcV
            │   │   ├── My.Lib.Config.mix
            │   │   ├── My.Lib.Types.mix
            │   │   └── My.Lib.Util.mix
            │   └── other-library-0.1.0.0-48EVZBwW9Kj29VTaRMhBDf
            │       ├── Other.Lib.A.mix
            │       └── Other.Lib.B.mix
            └── tix
                ├── all
                │   └── all.tix
                ├── my-library-0.1.0.0
                │   ├── my-library-0.1.0.0.tix
                │   ├── my-test-1
                │   │   └── my-test-1.tix
                │   └── unit-test
                │       └── unit-test.tix
                └── another-library-0.1.0.0
                    ├── another-library-0.1.0.0.tix
                    ├── my-test-2
                    │   └── my-test-2.tix
                    └── unit-test
                        └── unit-test.tix

All of the coverage information is copied verbatim from the coverage reports for each of the constituent packages. A few additions are made:

  • tix/all/all.tix is generated from the union of all the library tix files.
    • We use this file when generating coverage reports for "coveralls.io".
  • An index page (html/index.html) is generated which links to the HTML coverage reports of the constituent packages.
  • A synthetic HTML report is generated from the tix/all/all.tix file. This shows the union of all the coverage information generated by each constituent coverage report.

Making changes to Hix

When making changes to the way Hix works it is often useful to be able to test the changes locally before uploading them to github.

Hix Command Wrappers

Install the hix command wrappers after making changes to a local clone of haskell.nix:

nix-env -iA hix -f /path/to/local/haskell.nix
hix-shell

Or override the version of haskell.nix used by the commands with the HIX_ROOT environment variable:

HIX_ROOT=/path/to/local/haskell.nix hix-shell

Flakes

For flakes use --override-input to point to the modified haskell.nix:

nix develop --override-input haskellNix /path/to/local/haskell.nix

This file contains a summary of changes to Haskell.nix and nix-tools that will impact users.

Jul 27, 2022

  • Removed reliance on builtins.currentSystem. It was used it to provide pkgs.evalPackages via an overlay that it used to run derivations used in imports from derivation (IFDs).

    These derivations are now run on buildPackages by default.

    Passsing evalPackages to a project function will change where all the derivations used in IFDs are run for that project (including shell tools): evalPackages = import nixpkgs haskellNix.nixpkgsArgs;

    Passing evalSystem instead will use create a suitable nixpkgs using pkgs.path and pkgs.overlay: evalSystem = "x86_64-linux"; or evalSystem = builtins.currentSystem;

    The haskellLib.cleanGit function is also affected by this change. If you are cross compiling and using cleanGit you should probably do something like: pkgs = import nixpkgs haskellNix.nixpkgsArgs; evalPackages = import nixpkgs (haskellNix.nixpkgsArgs // { system = evalSystem; }); p = pkgs.pkgsCross.mingwW64.haskell-nix.cabalProject { inherit evalPackages; src = evalPackages.haskell-nix.haskellLib.cleanGit { src = ./.; }; };

Feb 16, 2022

  • Removed lookupSha256 argument from project functions. Pass a sha256map instead.
  • Added better support for repository in cabal.project. These blocks should now work without the need for passing extra-hackages and extra-hackage-tarballs.

Aug 6, 2021

  • Included dependencies of haskell.nix that were tracked in nix/sources.json as flake inputs (flake.lock replaces nix/sources.json).
  • Uses flake-compat to continue to provide a compatible interface for non flake projects.

Jul 23, 2021

  • source-repository-package references in cabal.project files are now left as a source-repository-package when calculating the the plan-nix for cabalProject based functions. This makes haskell.nix match the behaviour of cabal better. Materialized files for projects that use source-repository-package references will need to be updated.
  • Only planned components are included in a haskell.nix cabal project. If cabal solver does not include the component in the plan.json file it will not be present in hsPkgs.pkg.components.
  • When the same package occurs more than once in a plan.json file the latest version is picked by haskell.nix.

Apr 8, 2021

  • Project arguments are now validated with the Nix module system. If unexpected argments are passed to a project function this may now result in an error.

Feb 22, 2021

  • Add .dwarf to build any component with DWARF dubug info on linux (ghc >=8.10.2).
  • Pass enableDWARF to shellFor for to get a shell where all the components are the .dwarf ones.

Feb 18, 2021

  • ghcOptions has been moved from package and is now a list of strings. old: packages.x.package.ghcOptions = "someGHCoption"; new: packages.x.ghcOptions = ["someGHCoption"]; To specify ghcOptions for all packages: ghcOptions = ["someGHCoption"]; For a single component: packages.x.compoents.library.ghcOptions = ["someGHCoption"];

Feb 8, 2021

  • Removed older versions of haskell-language-server from custom-tools (0.8.0 is in hackage so we can still get that version).

Jan 14, 2021

  • Added support for cross package refs (with a project). Relative directory references between packages within a project should now work.
  • Added includeSiblings to cleanSourceWith. When true it prevents the subDir arg from causing filtering of other directories.
  • Added keepGitDir to cleanGit to allow .git directory to be kept (useful for components that use the githash package).

Nov 26, 2020

  • Renamed otherShells arg for shellFor to `inputsFrom

Nov 25, 2020

  • The shellFor makeConfigFiles ghcWithHoogle and ghcWithPackages functions have been removed from project.hsPkgs. Instead access them from project itself (e.g. change p.hsPkgs.shellFor to p.shellFor).
  • The reflex-platform like project.shells.ghc has been removed. If needed, add something like p // { shells.ghc = p.shellFor {} } to shell.nix.

Nov 24, 2020

  • Added ${targetPrefix}cabal wrapper script for running cross compilers in shellFor.
  • otherShells arg added to shellFor.

Oct 31, 2020

  • Passing tools.hoogle to shellFor with a value suitable for haskel-nix.tool will use the specified hoogle inside shellFor. This allows for materialization of hoogle.

Oct 28, 2020

  • Passing compiler-nix-name to project functions for stack.yaml based projects now overrides the compiler used (was ignored before).

Sep 8, 2020

  • Added the ability to generate coverage reports for packages and projects.
  • Added the doCoverage module option that allows users to choose packages to enable coverage for.
  • Added a doCoverage flag to the component builder that outputs HPC information when coverage is enabled.
  • Added test for coverage.

July 21, 2020

  • Removed components.all, use symlinkJoin on components.exes or shellFor if you need a shell.
  • Added components argument to shellFor.

July 21, 2020

  • Added GHC 8.8.4 and replaced 8.8.3 in tests and as the ghc used to build nix-tools for stack projects.

July 20, 2020

  • Changed haskell-nix.roots and p.roots to single derivations.

July 8, 2020

  • Removed sources.nixpkgs-default, use sources.nixpkgs instead.
  • Removed ./nixpkgs directory, use (import ./. {}).sources or ./nix/sources.nix instead.
  • Removes V1 interface for details on how to fix old code see: https://github.com/input-output-hk/haskell.nix/issues/709
  • Removed defaultCompilerNixName.
  • cabalProject, cabalProject', hackage-project and hackage-package now require a compiler-nix-name argument.
  • haskell-nix.tool and .tools now require a compiler-nix-name argument. New functions p.tool and p.tools (where p is a project) do not. Like shellFor { tools = ... } they will use the compiler nix name from the project (including stack projects where it is derived from the resolver).
  • haskell-nix.alex and haskell-nix.happy have been removed. Use p.tool "alex" "3.2.5" or shellFor { tools = { alex = "3.2.5"; } }.
  • haskell-nix.nix-tools -> haskell-nix.nix-tools.ghc883 (it includes the hpack exe now).
  • haskell-nix.cabal-install -> p.tool "cabal" "3.2.0.0" or shellFor { tools = { cabal = "3.2.0.0"; } }
  • haskell-nix.haskellNixRoots -> haskell-nix.roots ghc883 or p.roots

June 25, 2020

  • Haddock docs are now built in their own derivation when needed (not as part of the component build). They should build automatically when something (such as shellFor) attempts to accesses the .doc attribute of component.

December 27, 2019

  • Fix overlays/bootstrap.nix to provide LLVM 6, not LLVM 5, to ghc-8.6.X compilers.

November 18, 2019

  • Changed the cleanSourceHaskell to accept an attrset of src and (optional) name parameters. This allows you to keep the source derivation name constant, so that your builds are always cached. Usage of cleanSourceHaskell will need to be updated.

October 12, 2019

  • shellFor no longer sets CABAL_CONFIG by default. This avoids surprising users, but means that Cabal may select a plan which is different to your Haskell.nix package set. If you would like the old behaviour, use shellFor { exactDeps = true; }.

August 9, 2019

June 21, 2019

  • Add ghcWithPackages and ghcWithHoogle to hsPkgs (documentation.
  • Benchmark components can now build successfully.
  • Reduced the closure bloat of nix-tools, and added closure size limit to CI.
  • Added more reference documentation and set up auto-generated documentation for Module Options.
  • Miscellaneous bug fixes.

June 7, 2019

  • Several additions to the documentation.
    • More information about getting nix-tools, Haskell.nix, pinning.
    • Updates the stack-to-nix and cabal-to-nix guides.
    • Adds a section on development environments.
    • Adds a little information about cross compilation.
    • Adds a (partially complete) reference section (command line manuals, library reference).
    • Symlinks the changelog into the documentation pages.

May 29, 2019

  • Added shellFor function to package set.

May 28, 2019

  • Added snaphots and haskellPackages attributes to the Haskell.nix top-level.

May 22, 2019

  • Add the cleanSourceHaskell utility function to the Haskell.nix top-level.

May 21, 2019

  • Add the callCabalProjectToNix function, which uses "import from derivation" (IFD) so that nix-tools doesn't need to be run manually.
  • The hackage.nix update process has changed, so that Cabal index state hashes are also included in the generated repo.

May 20, 2019

  • Remove Travis CI in favour of Buildkite.

May 17, 2019

  • Add the callStackToNix function, which uses "import from derivation" (IFD) so that stack-to-nix doesn't need to be run manually.

Mar 15, 2019

  • overlays was renamed to extras in #79 to prevent confusion between the notion of Nix overlays.

    Therefore plan-pkgs and stack-pkgs as generated by plan-to-nix and stack-to-nix will expose extras instead of overlay. Similarly mkStackPkgSet, mkPkgSet and mkCabalProjectPkgSet take a pkg-def-extras instead of pkg-def-overlay argument. If you are using iohk-nix, the iohk-overlay was parameter was renamed to iohk-extras.