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.