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
See Nixpkgs current Users' Guide to Haskell Infrastructure for comparison.
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
: astack.yaml
to.nix
transformer that will read in astack.yaml
expression an generate apkgs.nix
file suited for use withhaskell.nix
. -
plan-to-nix
: aplan.json
to.nix
transformer that will read in aplan.json
file and generate apkgs.nix
file suited for use withhaskell.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
andstack
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 usecabal new‑build
to work on it. Starting Cabal 3.0cabal 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:
-
Run lorri watch to continuously build the shell environment and maintain GC roots.
-
Use emacs‑direnv to push the development environment into Emacs.
-
Use Dante for highlighting errors and auto-completion. You must customize Dante to prevent it from automatically using
nix‑shell
orstack
. Trimdante‑methods
to justnew‑build
andbare‑ghci
.You can also use
.dir‑locals.el
for this. If your project has multiple targets, setdante‑target
per-directory. -
For
haskell‑mode
interactive Haskell, sethaskell‑process‑type
tocabal‑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
— forpkgconfig-depends
.Each mapping entry is a list of packages.
-
lib/system-nixpkgs-map.nix
— forbuild-tool-depends
,frameworks
,extra-libraries
, etc.Each name can be mapped to:
- A single package from nixpkgs.
null
— eliminates the dependency- 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 whichsystem
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 useqemu
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:
- Disable dynamic linking
- 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 thaninteger-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 version | Nixpkgs pinning | GHC version | compiler-nix-name | Tested in CI? |
---|---|---|---|---|
22.05 | nixpkgs-2205 | 8.6.5 | ghc865 | No |
22.05 | nixpkgs-2205 | 8.10.7 | ghc8107 | No |
unstable | nixpkgs-unstable | 8.6.5 | ghc865 | No |
unstable | nixpkgs-unstable | 8.8.4 | ghc884 | No |
unstable | nixpkgs-unstable | 8.10.7 | ghc8107 | Yes |
unstable | nixpkgs-unstable | 9.0.2 | ghc902 | No |
unstable | nixpkgs-unstable | 9.2.4 | ghc924 | Yes |
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-name
s 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 — the kinds of data that you will encounter working with Haskell.nix.
- Top-level attributes — Functions and derivations defined in the Haskell.nix attrset.
- Package-set functions — Helper functions defined on the
hsPkgs
package set.
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 = { ... };
};
};
}
Attribute | Type | Description |
---|---|---|
options | Module options | The combination of all options set through the modules argument passed to mkPkgsSet . |
config | The result of evaluating and applying the options with Haskell.nix | |
.hsPkgs | Attrset of Haskell Packages | Buildable packages, created from packages |
.packages | Attrset of Haskell Package descriptions | Configuration for each package in hsPkgs |
.compiler | Attrset |
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:
- an attrset containing option declarations, or
- 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:
Argument | Type | Description |
---|---|---|
haskellLib | attrset | The haskellLib utility functions. |
pkgs | The Nixpkgs collection. | |
pkgconfPkgs | A 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:
Attribute | Type | Description |
---|---|---|
hsPkgs | Attrset of Haskell Packages | Buildable packages, created from packages |
stack-nix | projectNix attribute of callStackToNix return value | |
shellFor | Function | shellFor |
ghcWithHoogle | Function | ghcWithHoogle |
ghcWithPackages | Function | ghcWithPackages |
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:
Attribute | Type | Description |
---|---|---|
hsPkgs | Attrset of Haskell Packages | Buildable packages, created from packages |
plan-nix | projectNix attribute of callCabalProjectToNix return value | |
index-state | index-state attribute of callCabalProjectToNix return value | |
shellFor | Function | shellFor |
ghcWithHoogle | Function | ghcWithHoogle |
ghcWithPackages | Function | ghcWithPackages |
projectCross | Attrset | Like 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 |
projectVariants | Attrset | Attribute set of variant for the project, mapped from flake.variants config values |
appendModule | Function | Re-eval the project with an extra module (or module list). |
extend and appendOverlays | Function | Modify 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 ? []}: ...
Argument | Type | Description |
---|---|---|
stack-pkgs | import ./pkgs.nix — The imported file generated by stack‑to‑nix . | |
pkg‑def‑extras | List of Extras | For overriding the package set. |
modules | List of Modules | For 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 ? []}: ...
Argument | Type | Description |
---|---|---|
plan-pkgs | import ./pkgs.nix — The imported file generated by plan‑to‑nix . | |
pkg‑def‑extras | List of Extras | For overriding the package set. |
modules | List of Modules | For 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;
Argument | Type | Description |
---|---|---|
name | String | Optional name for better error messages. |
src | Path | Location of the cabal project files. |
compiler-nix-name | String | The name of the ghc compiler to use eg. "ghc884" |
index-state | Timestamp | Optional hackage index-state, eg. "2019-10-10T00:00:00Z". |
index-sha256 | Sha256 | Optional hash of the truncated hackage index-state. |
plan-sha256 | Sha256 | Optional hash of the plan-to-nix output (makes the plan-to-nix step a fixed output derivation). |
cabalProject | String | Optional cabal project file contents (defaults to readFile "${src}/cabal.project"). |
cabalProjectLocal | String | Optional cabal project file contents (defaults to readFile "${src}/cabal.project.local"). |
cabalProjectFreeze | String | Optional cabal project file contents (defaults to readFile "${src}/cabal.project.freeze"). |
ghc | Deprecated. Use compiler-nix-name instead. Optional ghc to use | |
nix-tools | Optional nix-tools to use | |
hpack | Optional hpack to use | |
cabal-install | Optional cabal-install to use | |
configureArgs | String | Optional 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:
Attribute | Type | Description |
---|---|---|
pkgs | attrset | that can be passed to mkStackPkgSet (as stack-pkgs ) or mkCabalProjectPkgSet (as plan-pkgs ). |
nix | this 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)
Argument | Type | Description |
---|---|---|
group | String | A sub-component type. |
packageSel | A function Package -> Bool | A predicate to filter packages with. |
haskellPackages | Package set | All 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.
Argument | Type | Description |
---|---|---|
drv | Derivation | One 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, ...}: ...
Argument | Type | Description |
---|---|---|
packages | Function | Package selection function. It takes a list of Haskell packages and returns a subset of these packages. |
components | Function | Similar to packages , by default all the components of the selected packages are selected. |
additional | Function | Similar to packages , but the selected packages are built and included in ghc-pkg list (not just their dependencies). |
withHoogle | Boolean | Whether to build a Hoogle documentation index and provide the hoogle command. |
exactDeps | Boolean | Prevents the Cabal solver from choosing any package dependency other than what are in the package set. |
tools | Function | AttrSet 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. |
inputsFrom | List | List of other shells to include in this one. The buildInputs and nativeBuildInputs of each will be included using mkShell. |
crossPlatforms | Function | Platform selection function for cross compilation targets to support eg. ps: with ps; [ghcjs mingwW64] (see nixpkgs lib.systems.examples for list of platform names). |
{ ... } | Attrset | All the other arguments are passed to mkDerivation . |
Return value: a derivation
⚠️ Warning:
exactDeps = true
will set theCABAL_CONFIG
environment variable to disable remote package servers. This is a known limitation which we would like to solve. UseexactDeps = 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
: ThespecialArgs
argument passed toevalModules
. -
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 thenixpkgs
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
-
Use niv to update the sources.json:
nix flake lock --update-input nix-tools
-
If
nix-tools.cabal
orplan-to-nix
have changed, check the materialized files for each of the compiler nix name inls -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 likehaskell-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
)
- 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:
- 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 theshare/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 providepkgs.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 suitablenixpkgs
usingpkgs.path
andpkgs.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 usingcleanGit
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
incabal.project
. These blocks should now work without the need for passingextra-hackages
andextra-hackage-tarballs
.
Aug 6, 2021
- Included dependencies of haskell.nix that were tracked in
nix/sources.json
as flake inputs (flake.lock
replacesnix/sources.json
). - Uses
flake-compat
to continue to provide a compatible interface for non flake projects.
Jul 23, 2021
source-repository-package
references incabal.project
files are now left as asource-repository-package
when calculating the theplan-nix
forcabalProject
based functions. This makes haskell.nix match the behaviour ofcabal
better. Materialized files for projects that usesource-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 inhsPkgs.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
toshellFor
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
tocleanSourceWith
. Whentrue
it prevents thesubDir
arg from causing filtering of other directories. - Added
keepGitDir
tocleanGit
to allow.git
directory to be kept (useful for components that use thegithash
package).
Nov 26, 2020
- Renamed
otherShells
arg forshellFor
to `inputsFrom
Nov 25, 2020
- The
shellFor
makeConfigFiles
ghcWithHoogle
andghcWithPackages
functions have been removed fromproject.hsPkgs
. Instead access them fromproject
itself (e.g. changep.hsPkgs.shellFor
top.shellFor
). - The reflex-platform like
project.shells.ghc
has been removed. If needed, add something likep // { shells.ghc = p.shellFor {} }
toshell.nix
.
Nov 24, 2020
- Added
${targetPrefix}cabal
wrapper script for running cross compilers inshellFor
. otherShells
arg added toshellFor
.
Oct 31, 2020
- Passing
tools.hoogle
toshellFor
with a value suitable forhaskel-nix.tool
will use the specifiedhoogle
insideshellFor
. This allows for materialization ofhoogle
.
Oct 28, 2020
- Passing
compiler-nix-name
to project functions forstack.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
, usesymlinkJoin
on components.exes orshellFor
if you need a shell. - Added
components
argument toshellFor
.
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
andp.roots
to single derivations.
July 8, 2020
- Removed
sources.nixpkgs-default
, usesources.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 acompiler-nix-name
argument. New functionsp.tool
andp.tools
(where p is a project) do not. LikeshellFor { tools = ... }
they will use the compiler nix name from the project (including stack projects where it is derived from the resolver).haskell-nix.alex
andhaskell-nix.happy
have been removed. Usep.tool "alex" "3.2.5"
orshellFor { 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"
orshellFor { tools = { cabal = "3.2.0.0"; } }
haskell-nix.haskellNixRoots
->haskell-nix.roots ghc883
orp.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 ofsrc
and (optional)name
parameters. This allows you to keep the source derivation name constant, so that your builds are always cached. Usage ofcleanSourceHaskell
will need to be updated.
October 12, 2019
shellFor
no longer setsCABAL_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, useshellFor { exactDeps = true; }
.
August 9, 2019
- Add the
haskellLib.collectComponents
function.
June 21, 2019
- Add
ghcWithPackages
andghcWithHoogle
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
andhaskellPackages
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 thatstack-to-nix
doesn't need to be run manually.
Mar 15, 2019
-
overlays
was renamed toextras
in #79 to prevent confusion between the notion of Nix overlays.Therefore
plan-pkgs
andstack-pkgs
as generated byplan-to-nix
andstack-to-nix
will exposeextras
instead ofoverlay
. SimilarlymkStackPkgSet
,mkPkgSet
andmkCabalProjectPkgSet
take apkg-def-extras
instead ofpkg-def-overlay
argument. If you are usingiohk-nix
, theiohk-overlay
was parameter was renamed toiohk-extras
.