on iko/ghcjs-patch-master help sign in
Update the docs (#165)

The docs are not complete yet, but we can start improving them from here.

commit3747f543573cf64a5a53047542987397b306189d authorRodney Lorrimar <rodney.lorrimar@iohk.io> dateFri 7 Jun 2019, 14:46 (7 years ago) parent17c345f
18 files changed+877−205
.gitignore+6 changelog.md+22−4 docs/architecture.md+11−7 docs/changelog.md+1 docs/index.md+5−1 docs/migrations.md−13 docs/reference/commands.md+75 docs/reference/library.md+173 docs/reference/modules.md+4 docs/user-guide-cabal.md−64 docs/user-guide-stack.md−39 docs/user-guide.md+117−75 docs/user-guide/cabal-projects.md+82 docs/user-guide/cross-compilation.md+105 docs/user-guide/development.md+144 docs/user-guide/projects.md+61 docs/user-guide/stack-projects.md+56 mkdocs.yml+15−2
.gitignore+6
@@ -1,3 +1,9 @@
1+# The output of "mkdocs build"
2+/site/
3+
4+# Nix build results
5+result*
6+/nt
17
28# Created by https://www.gitignore.io/api/haskell,emacs,vim
39
changelog.md+22−4
@@ -1,3 +1,15 @@
1+This file contains a summary of changes to Haskell.nix and `nix-tools`
2+that will impact users.
3+
4+## June 7, 2019
5+ * Several additions to the [documentation](https://input-output-hk.github.io/haskell.nix/).
6+ * More information about getting nix-tools, Haskell.nix, pinning.
7+ * Updates the stack-to-nix and cabal-to-nix guides.
8+ * Adds a section on development environments.
9+ * Adds a little information about cross compilation.
10+ * Adds a (partially complete) reference section (command line manuals, library reference).
11+ * Symlinks the changelog into the documentation pages.
12+
113## May 29, 2019
214 * Added `shellFor` function to package set.
315
@@ -8,7 +20,7 @@
820## May 22, 2019
921 * Add the `cleanSourceHaskell` utility function to the Haskell.nix
1022 top-level.
11−
23+
1224## May 21, 2019
1325 * Add the `callCabalProjectToNix` function, which uses "import from
1426 derivation" (IFD) so that nix-tools doesn't need to be run
@@ -23,7 +35,13 @@
2335 * Add the `callStackToNix` function, which uses "import from
2436 derivation" (IFD) so that `stack-to-nix` doesn't need to be run
2537 manually.
26−
38+
2739## Mar 15, 2019
28− * overlays was renamed to extras (#79)
29− See docs/migration.md
40+ * `overlays` was renamed to `extras` in
41+ [#79](https://github.com/input-output-hk/haskell.nix/pull/79)
42+ to prevent confusion between the notion of Nix overlays.
43+
44+ Therefore `plan-pkgs` and `stack-pkgs` as generated by `plan-to-nix` and `stack-to-nix` will
45+ expose `extras` instead of `overlay`. Similarly `mkStackPkgSet`, `mkPkgSet` and `mkCabalProjectPkgSet`
46+ take a `pkg-def-extras` instead of `pkg-def-overlay` argument. If you are using `iohk-nix`, the
47+ `iohk-overlay` was parameter was renamed to `iohk-extras`.
docs/architecture.md+11−7
@@ -43,22 +43,26 @@ nix-tools is a Haskell package that provides the following tools:
4343
4444as well as a few other tools used to generate `hackage.nix` and `stackage.nix`.
4545
46−## [haskell.nix](https://github.com/input-output-hk/haskell.nix)
46+## [haskell.nix][]
4747
48−haskell.nix is the runtime system for this Haskell infrastructure. It
49−contains the component builder, as well as the system package and
48+[Haskell.nix][] is the runtime system for this Haskell infrastructure.
49+It contains the component builder, as well as the system package and
5050license mapping. Without haskell.nix the expressions generated by
5151either of the `nix-tools` tools make little sense on their own.
5252
53−## [hackage.nix](https://github.com/input-output-hk/hackage.nix)
53+## [hackage.nix][]
5454
55−hackage.nix provides all cabal expressions from hackage as nix
55+[hackage.nix][] provides all cabal expressions from hackage as nix
5656expressions. It is periodically updated to keep in sync with the set
5757of packages available on hackage.
5858
59−## [stackage.nix](https://github.com/input-output-hk/stackage.nix)
59+## [stackage.nix][]
6060
61−stackage.nix is similar to hackage.nix but provides all stackage
61+[stackage.nix][] is similar to hackage.nix but provides all stackage
6262snapshots (lts, and nightly) as nix expressions. It naturally depends
6363on hackage.nix to resolve package names, versions and revisions to the
6464repsective packages from hackage.nix.
65+
66+[haskell.nix]: https://github.com/input-output-hk/haskell.nix
67+[hackage.nix]: https://github.com/input-output-hk/hackage.nix
68+[stackage.nix]: https://github.com/input-output-hk/stackage.nix
docs/changelog.mdnew file+1
@@ -0,0 +1 @@
1+../changelog.md
docs/index.md+5−1
@@ -1,7 +1,11 @@
11# haskell.nix
22
33haskell.nix is an alternative Haskell infrastructure for nixpkgs. See
4−[Nixpkgs current Users' Guide to Haskell Infrastructure](https://nixos.org/nixpkgs/manual/#users-guide-to-the-haskell-infrastructure) for comparison.
4+[Nixpkgs current Users' Guide to Haskell Infrastructure][nixpkgs] for
5+comparison.
6+
7+[nixpkgs]: https://nixos.org/nixpkgs/manual/#users-guide-to-the-haskell-infrastructure
8+[issues]: https://github.com/input-output-hk/haskell.nix/issues
59
610## Motivation
711
docs/migrations.mddeleted−13
@@ -1,13 +0,0 @@
1−# `overlay` to `extras`
2−
3−`overlay` was renamed to `extras` in #79 to prevent confusion between the notion of nix overlays.
4−Therefore `plan-pkgs` and `stack-pkgs` as generated by `plan-to-nix` and `stack-to-nix` will
5−expose `extras` instead of `overlay`. Similarly `mkStackPkgSet`, `mkPkgSet` and `mkCabalProjectPkgSet`
6−take a `pkg-def-extras` instead of `pkg-def-overlay` argument. If you are using `iohk-nix`, the
7−`iohk-overlay` was parameter was renamed to `iohk-extras`.
8−
9−# Drop `th-packages`
10−
11−When using `iohk-nix` to facility cross compilation, we used to require explicit listing of packages
12−that required `TemplateHaskell`, this was dropped in [iohk-nix@da7c1ed](https://github.com/input-output-hk/iohk-nix/commit/da7c1edc31d24ff4a211b7dc2361c71af7c3bda4), see #92.
13−As such the `th-packages` and `nixpkgs` argument were dropped from the `iohk-module`.
docs/reference/commands.mdnew file+75
@@ -0,0 +1,75 @@
1+# stack-to-nix
2+
3+```
4+stack-to-nix - a stack to nix converter
5+
6+Usage: stack-to-nix (-o|--output DIR) [--stack-yaml FILE]
7+ [--ignore-package-yaml] [--cache FILE]
8+ Generate a Nix expression for a Haskell package using Stack
9+
10+Available options:
11+ -o,--output DIR Generate output in DIR
12+ --stack-yaml FILE Override project stack.yaml (default: "stack.yaml")
13+ --ignore-package-yaml disable hpack run and use only cabal disregarding
14+ package.yaml existence
15+ --cache FILE Dependency cache
16+ file (default: ".stack-to-nix.cache")
17+ -h,--help Show this help text
18+```
19+
20+Use this for stack projects. If a `default.nix` does not exist in the
21+output directory, it will create a basic one with a
22+[`mkStackPkgSet`](../user-guide/stack-projects.md) function.
23+
24+!!! note
25+ If you find that there are missing files which should have been
26+ generated, remove `.stack-to-nix.cache`. (There's an open issue for
27+ this).
28+
29+# plan-to-nix
30+
31+```
32+plan-to-nix - a stack to nix converter
33+
34+Usage: plan-to-nix (-o|--output DIR) [--plan-json FILE] [--cabal-project FILE]
35+ [--cache FILE]
36+ Generate a Nix expression for a Haskell package using Cabal
37+
38+Available options:
39+ -o,--output DIR Generate output in DIR
40+ --plan-json FILE Override plan.json
41+ location (default: "dist-newstyle/cache/plan.json")
42+ --cabal-project FILE Override path to
43+ cabal.project (default: "cabal.project")
44+ --cache FILE Dependency cache file (default: ".nix-tools.cache")
45+ -h,--help Show this help text
46+```
47+
48+Use this for Cabal new-build projects (even if you don't have a
49+`cabal.project`). Before running, you need to create a plan. For more
50+information, see [Cabal Projects](../user-guide/cabal-projects.md) in the user
51+guide.
52+
53+It will create a template `default.nix` in the output directory,
54+unless that file already exists.
55+
56+Inside the output directory, there will be another directory
57+`.plan.nix`, which contains Nix expressions for all local packages,
58+generated by `cabal-to-nix`. The output file `pkgs.nix` refers to
59+these files.
60+
61+Same note as above applies about the cache file.
62+
63+# cabal-to-nix
64+
65+```
66+Usage: cabal-to-nix FILE.cabal
67+```
68+
69+This writes (to stdout) a [Haskell.nix][] Nix expression for the given
70+cabal package.
71+
72+Normally, you do not need to run `cabal-to-nix` yourself. It is called
73+by `stack-to-nix` and `plan-to-nix`.
74+
75+[haskell.nix]: https://github.com/input-output-hk/haskell.nix
docs/reference/library.mdnew file+173
@@ -0,0 +1,173 @@
1+[Haskell.nix][] contains a library of functions for creating buildable
2+package sets from their Nix expression descriptions. The library is
3+what you get when importing [Haskell.nix][]. It might be helpful to
4+load the library in the [Nix REPL](../user-guide.md#using-nix-repl) to
5+test things.
6+
7+# Types
8+
9+## Package Set
10+
11+The result of `mkPkgSet`. This is an application of the NixOS module
12+system.
13+
14+```
15+{
16+ options = { ... };
17+ config = {
18+ hsPkgs = { ... };
19+ packages = { ... };
20+ compiler = {
21+ version = "X.Y.Z";
22+ nix-name = "ghcXYZ";
23+ packages = { ... };
24+ };
25+ };
26+}
27+```
28+
29+| Attribute | Type | Description |
30+|----------------|------|-----------------------------------------------------|
31+| `options` | Module options | The combination of all options set through the `modules` argument passed to `mkPkgsSet`. |
32+| `config` | | The result of evaluating and applying the `options` with [Haskell.nix][] |
33+| `.hsPkgs` | Attrset of [Haskell Packages](#haskell-package) | Buildable packages, created from `packages` |
34+| `.packages` | Attrset of [Haskell Package descriptions](#haskell-package-descriptions) | Configuration for each package in `hsPkgs` |
35+| `.compiler` | Attrset | |
36+
37+
38+
39+## Haskell Package description
40+
41+Options for building a package. (todo: more info)
42+
43+## Component description
44+
45+Options for building a component. (todo: more info)
46+
47+## Haskell Package
48+
49+A derivation which has a `components` attribute. This derivation is
50+actually just for the package `Setup.hs` script, and isn't very
51+interesting. To actually use the package, look within the components
52+structure.
53+
54+```
55+components = {
56+ library = COMPONENT;
57+ exes = { NAME = COMPONENT; };
58+ tests = { NAME = COMPONENT; };
59+ benchmarks = { NAME = COMPONENT; };
60+ all = COMPONENT;
61+}
62+```
63+
64+## Component
65+
66+## Identifier
67+
68+A package identifier is an attrset pair of `name` and `version`.
69+
70+## Extras
71+
72+## Modules
73+
74+# Top-level attributes
75+
76+## mkStackPkgSet
77+
78+Creates a [package set](#package-set) based on the `pkgs.nix` output
79+of `stack-to-nix`.
80+
81+```nix
82+mkStackPkgSet =
83+ { stack-pkgs, pkg-def-extras ? [], modules ? []}: ...
84+```
85+
86+| Argument | Type | Description |
87+|------------------|------|---------------------|
88+| `stack-pkgs` | | `import ./pkgs.nix` — The imported file generated by `stack‑to‑nix`. |
89+| `pkg‑def‑extras` | List of [Extras](#extras) | For overriding the package set. |
90+| `modules` | List of [Modules](#modules) | For overriding the package set. |
91+
92+**Return value**: a [`pkgSet`](#package-set)
93+
94+## mkCabalProjectPkgSet
95+
96+Creates a [package set](#package-set) based on the `pkgs.nix` output
97+of `plan-to-nix`.
98+
99+```nix
100+mkCabalProjectPkgSet =
101+ { plan-pkgs, pkg-def-extras ? [], modules ? []}: ...
102+```
103+
104+| Argument | Type | Description |
105+|------------------|------|---------------------|
106+| `plan-pkgs` | | `import ./pkgs.nix` — The imported file generated by `plan‑to‑nix`. |
107+| `pkg‑def‑extras` | List of [Extras](#extras) | For overriding the package set. |
108+| `modules` | List of [Modules](#modules) | For overriding the package set. |
109+
110+**Return value**: a [`pkgSet`](#package-set)
111+
112+## mkPkgSet
113+
114+This is the base function used by both `mkStackPkgSet` and
115+`mkCabalProjectPkgSet`.
116+
117+**Return value**: a [`pkgSet`](#package-set)
118+
119+## snapshots
120+
121+This is an attrset of `hsPkgs` packages from Stackage.
122+
123+## haskellPackages
124+
125+A `hsPkgs` package set
126+
127+## nix-tools
128+
129+A derivation containing the `nix-tools` [command-line tools](commands.md).
130+
131+## callStackToNix
132+
133+## callCabalProjectToNix
134+
135+## hackage
136+## stackage
137+
138+## fetchExternal
139+
140+## cleanSourceHaskell
141+
142+## haskellLib
143+
144+# Package-set functions
145+
146+These functions exist within the `hsPkgs` package set.
147+
148+## shellFor
149+
150+Create a `nix-shell` [development
151+environment](../user-guide/development.md) *for* developing one or
152+more packages.
153+
154+```
155+shellFor =
156+ { packages, withHoogle ? true, ...}: ...
157+```
158+
159+
160+| Argument | Type | Description |
161+|----------------|------|---------------------|
162+| `packages` | Function | Package selection function. It takes a list of [Haskell packages](#haskell-package) and returns a subset of these packages. |
163+| `withHoogle` | Boolean | Whether to build a Hoogle documentation index and provide the `hoogle` command. |
164+| `{ ... }` | Attrset | All the other arguments are passed to [`mkDerivation`](https://nixos.org/nixpkgs/manual/#sec-using-stdenv). |
165+
166+**Return value**: a derivation
167+
168+## ghcWithPackages
169+
170+## ghcWithHoogle
171+
172+
173+[haskell.nix]: https://github.com/input-output-hk/haskell.nix
docs/reference/modules.mdnew file+4
@@ -0,0 +1,4 @@
1+Haskell.nix modules options for packages and components.
2+
3+!!! note "Undocumented"
4+ Please help write me.
docs/user-guide-cabal.mddeleted−64
@@ -1,64 +0,0 @@
1−# User Guide (cabal project)
2−
3−Here we will look into how to generate the `pkgs.nix` file for a
4−`cabal.project` project. For the full integration please see the [User
5−Guide](/user-guide)
6−
7−## Using `plan-to-nix`
8−
9−*We currently don't have a `project-to-nix` tool yet, as such creating
10− the relevant `pkgs.nix` file for a `cabal.project` is slightly more
11− involved than for a corresponding stack project*.
12−
13−With [nix-tools](https://github.com/input-output-hk/nix-tools) in
14−`PATH`, we can simply run the following command on a cabal package:
15−
16−```bash
17−# make sure the cabal project is configured (the plan.json file is generated)
18−cabal new-configure
19−# convert the plan.json file into a pkgs.nix file
20−plan-to-nix dist-newstyle/cache/plan.json > nix/plan.nix
21−```
22−
23−This will produce a `nix/plan.nix` file that looks like the following:
24−```nix
25−hackage:
26− {
27− packages = {
28− "o-clock" = hackage.o-clock."0.1.1".revisions.default;
29− ...
30− };
31− compiler = { ... };
32− }
33−```
34−
35−it specifically does not include any of our local packages yet. We
36−will need to run
37−
38−```bash
39−cabal-to-nix $path > nix/$pkg.nix
40−```
41−or
42−```bash
43−cabal-to-nix $url $rev > nix/$pkg.nix
44−```
45−for each local (or source) package.
46−
47−With this in place we can then proceed to build the `nix/pkgs.nix`
48−file as follows:
49−
50−```nix
51−let plan = import ./plan.nix; in
52−{ pkg-def = plan;
53− extras =
54− { local-package-a = ./local-package-a.nix;
55− local-package-b = ./local-package-b.nix;
56− source-import-a = ./source-import-a.nix;
57− source-import-b = ./source-import-b.nix;
58− ...
59− };
60−}
61−```
62−
63−*If you came here from the [User Guide](/user-guide), go back and
64− complete the setup.*
docs/user-guide-stack.mddeleted−39
@@ -1,39 +0,0 @@
1−# User Guide (stack project)
2−
3−Here we will look into how to generate the `pkgs.nix` file for a
4−`stack.yaml` project. For the full integration please see the [User
5−Guide](/user-guide)
6−
7−## Using `stack-to-nix`
8−
9−With [nix-tools](https://github.com/input-output-hk/nix-tools) in
10−`PATH`, we can simply run the following command on a stack project:
11−
12−```bash
13−stack-to-nix -o nix --stack-yaml stack.yaml
14−```
15−
16−This will produce a `nix/pkgs.nix` file that looks like the following:
17−```nix
18−{
19− resolver = "lts-12.17";
20− extras = hackage:
21− {
22− packages = {
23− "o-clock" = hackage.o-clock."0.1.1".revisions.default;
24− ...
25− } // {
26− my-package = ./my-package.nix;
27− ...
28− };
29− };
30−}
31−```
32−
33−This file contains the stackage resolver, as well as set of extra
34−packages. The extras specifies which `extra-deps` (here: o-clock-0.1.1)
35−we wanted to add over the stackage snapshot, and what local
36−packages we want (here: my-package).
37−
38−*If you came here from the [User Guide](/user-guide), go back and
39− complete the setup.*
docs/user-guide.md+117−75
@@ -1,10 +1,12 @@
11# User Guide
22
3−So you want to use `haskell.nix` with your stack or cabal project. The
4−general approach will be to pick the right tool from `nix-tools` and
5−produce a `pkgs.nix` expressions. Getting a copy of the haskell.nix,
6−hackage.nix (and potentially stackage.nix) source will then equip us
7−to produce derivations that we can `nix build`.
3+So you want to use [Haskell.nix][] with your stack or cabal project. The
4+general approach will be to pick the right tool from `nix-tools` and
5+produce a `pkgs.nix` expression. Getting a copy of the `nix-tools`
6+(and potentially the [Haskell.nix][] source), will then equip us to
7+produce derivations that we can `nix build`.
8+
9+[haskell.nix]: https://github.com/input-output-hk/haskell.nix
810
911## Installing `nix-tools`
1012
@@ -20,101 +22,141 @@ If you would like to then install `nix-tools` into your profile, run:
2022nix-env -i ./nt
2123```
2224
23−## Setup
25+## Getting the [Haskell.nix][] source (optional)
2426
25−The general structure will be the same for haskell.nix, independent of
26−the use of stack or cabal. Let us assume for now that we have
27−generated a `pkgs.nix` expression in `nix`.
27+The [Haskell.nix][] and `nix-tools` source will be useful if you would
28+like to contribute improvements, or read the source code to fully
29+understand something that the documentation doesn't cover.
2830
29−- [Generating a `pkgs.nix` for a stack project](/user-guide-stack)
30−- [Generating a `pkgs.nix` for a cabal project](/user-guide-cabal)
31+```bash
32+git clone https://github.com/input-output-hk/nix-tools
33+git clone https://github.com/input-output-hk/haskell.nix
34+cd haskell.nix
35+nix build -f . nix-tools --out-link nt
36+```
3137
32−## default.nix
38+## Importing [Haskell.nix][] into your project
3339
34−We will start with defining a helper function in our `default.nix`
35−that will allow us to override the source imports with `-I
36−haskell=/path/to/haskell.nix` in case we need it.
40+The easiest way to get a hold of [Haskell.nix][] is with
41+[`fetchTarball`](https://nixos.org/nix/manual/#ssec-builtins).
3742
3843```nix
39−{ pkgs ? import <nixpkgs> {}
40−}:
41−let
42− overrideWith = override: default:
43− let
44− try = builtins.tryEval (builtins.findFile builtins.nixPath override);
45− in if try.success then
46− builtins.trace "using search host <${override}>" try.value
47− else
48− default;
49−in
44+import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {}
45+```
46+
47+If you have your own `pkgs` variable, pass it to [Haskell.nix][] to
48+prevent double-evaluation of the Nixpkgs collection.
49+
50+```nix
51+{ pkgs ? import <nixpkgs> {} }:
52+
53+import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) { inherit pkgs; }
5054```
5155
52−Next we will use this to import `haskell.nix`.
56+### Pinning the [Haskell.nix][] version
57+
58+For simplicity's sake we will use `fetchTarball` for the examples in
59+this documentation. This will always get the latest version, and is
60+similar to an auto-updating Nix channel.
61+
62+However, in your own project, you may wish to pin [Haskell.nix][] (as
63+you would pin Nixpkgs). This will make your builds reproducable, more
64+predictable, and faster (because the fixed version is cached).
5365
54−**NOTE**: update the `rev` and `sha256` values to the recent ones as
55− found on GitHub. Especially `haskell.hackage` and `haskell.stackage`
56− will evolve with package release on hackage and stackage releases
57− respectively.
66+One way of doing this is to use `nix-prefetch-git` to get a JSON file
67+with a revision and SHA-256 hash of [Haskell.nix][].
68+
69+```
70+$ nix-prefetch-git --quiet https://github.com/input-output-hk/haskell.nix | tee haskell-nix-src.json
71+{
72+ "url": "https://github.com/input-output-hk/haskell.nix",
73+ "rev": "f1a94a4c82a2ab999a67c3b84269da78d89f0075",
74+ "date": "2019-06-05T01:06:12+00:00",
75+ "sha256": "0ggxsppjlb6q6a83y12cwgrdnqnw1s128rpibgzs5p1966bdfqla",
76+ "fetchSubmodules": false
77+}
78+```
79+
80+(The `tee` command is just to show you the result.)
81+Use the following expression to import that version:
5882
5983```nix
84+{ pkgs ? import <nixpkgs> {} }:
85+
6086let
61− haskellLib = pkgs.fetchFromGitHub {
62− owner = "input-output-hk";
63− repo = "haskell.nix";
64− rev = "5180ae9d78756509c81b98b8e6d974e350b15752";
65− sha256 = "0fbnnvymdp2qb09wlqy6ga8wsyhglx607cjdfg510s1gs756v9yx";
66− name = "haskell-lib-source";
87+ spec = builtins.fromJSON (builtins.readFile ./haskell-nix-src.json);
88+ haskell-nix-src = pkgs.fetchgit {
89+ name = "haskell-lib";
90+ inherit (spec) url rev sha256 fetchSubmodules;
6791 };
68− haskell = import (overrideWith "haskell" haskellLib) { inherit pkgs; };
6992in
93+ import haskell-nix-src { inherit pkgs; }
7094```
7195
72−Finally we string this together and produce a package set:
96+There are other possible schemes for pinning. See
97+[`haskell.nix/lib/fetch-external.nix`](https://github.com/input-output-hk/haskell.nix/blob/master/lib/fetch-external.nix),
98+the [niv](https://github.com/nmattia/niv) tool, or the Nix Flakes
99+proposal.
100+
101+### Overriding the Hackage version
102+
103+Sometimes you might want to use a chosen version of Haskell.nix with a
104+recent update of Hackage or Stackage. This can be done with JSON pins:
105+
106+```bash
107+nix-prefetch-git https://github.com/input-output-hk/hackage.nix | tee hackage-src.json
108+nix-prefetch-git https://github.com/input-output-hk/stackage.nix | tee stackage-src.json
109+```
110+
111+The resulting JSON files will correspond to the latest revision of
112+[hackage.nix][] and [stackage.nix][]. See
113+[Architecture](architecture.md) for more information about how
114+these Git repositories correspond to the actual Hackage and Stackage.
115+
116+[hackage.nix]: https://github.com/input-output-hk/hackage.nix
117+[stackage.nix]: https://github.com/input-output-hk/stackage.nix
73118
74119```nix
75−let
76− # Import the file you will create in the stack-to-nix or cabal-to-nix step.
77− my-pkgs = import ./nix/pkgs.nix;
78−
79− # Stack projects use the mkStackPkgSet helper function
80− pkgSet = haskell.mkStackPkgSet {
81− stack-pkgs = my-pkgs;
82− pkg-def-overlays = [];
83− modules = [];
84− };
120+{ pkgs ? import <nixpkgs> {} }:
85121
86− # Cabal projects use mkPkgSet
87− pkgSet = haskell.mkPkgSet {
88− pkg-def = my-pkgs.pkg-def;
89− pkg-def-extras = [
90− # these extras will provide additional packages
91− # ontop of the package set. E.g. extra-deps
92− # for stack packages. or local packages for
93− # cabal.projects
94− my-pkgs.extras
95− ];
96− modules = [
97− # specific package overrides would go here
98− # example:
99− # packages.cbors.patches = [ ./one.patch ];
100− # packages.cbors.flags.optimize-gmp = false;
101− ];
102− };
122+import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {
123+ inherit pkgs;
124+ hackageSourceJSON = ./hackage-src.json;
125+ stackageSourceJSON = ./stackage-src.json;
126+}
127+```
128+
129+## Using `nix repl`
103130
104−in pkgSet.config.hsPkgs // { _config = pkgSet.config; }
131+It's sometimes useful to load [Haskell.nix][] in the REPL to explore
132+attrsets and try examples.
133+
134+```
135+# example.nix
136+{ pkgs ? import <nixpkgs> {} }:
137+rec {
138+ haskell = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) { inherit pkgs; };
139+ pkgNames = pkgs.lib.attrNames haskell.snapshots."lts-13.18";
140+}
105141```
106142
107−With this setup you can then start building the components of
108−interest:
143+Load the example file:
109144
110−```bash
111−nix build -f default.nix $pkg.components.library
112145```
146+$ nix repl '<nixpkgs>' example.nix
147+Welcome to Nix version 2.3pre6631_e58a7144. Type :? for help.
113148
114−to build the library for `$pkg` or
149+Loading '<nixpkgs>'...
150+Added 10403 variables.
115151
116−```bash
117−nix build -f default.nix $pkg.components.exes.$exe
152+Loading 'example2.nix'...
153+Added 2 variables.
154+
155+nix-repl> lib.take 5 pkgNames
156+[ "ALUT" "ANum" "Allure" "Boolean" "BoundedChan" ]
157+
158+nix-repl>
118159```
119160
120−to build a specific executable. The same holds for test suites and benchmarks.
161+Now that you have `nix-tools` and are able to import [Haskell.nix][],
162+you can continue to the next chapter.
docs/user-guide/cabal-projects.mdnew file+82
@@ -0,0 +1,82 @@
1+Here we will look into how to generate the `pkgs.nix` file for a
2+`cabal.project` project. For the full integration see the [previous
3+page](./projects.md).
4+
5+Generating package sets for Cabal projects, is slightly more involved,
6+because you need to let Cabal calculate a build plan for the
7+dependencies of your package(s).
8+
9+## Generating `plan.json`
10+
11+To get a plan, you need Cabal and GHC. See the [Nixpkgs
12+Manual](https://nixos.org/nixpkgs/manual/#how-to-install-a-compiler)
13+for information about how to choose a specific compiler version.
14+
15+For this example, we will run a `nix-shell` with the default GHC
16+version for Nixpkgs.
17+
18+```bash
19+nix-shell -p haskellPackages.cabal-install haskellPackages.ghc \
20+ --run "cabal new-configure"
21+```
22+
23+If all goes well, you should now have the file
24+`dist-newstyle/cache/plan.json`.
25+
26+## Using `plan-to-nix`
27+
28+With [nix-tools installed](../user-guide.md), we can then run the
29+following command on a Cabal project and its build plan. Omit the
30+`--cabal-project` option if you don't have a project file.
31+
32+```bash
33+# convert the plan.json file into a pkgs.nix file
34+plan-to-nix --output . \
35+ --plan-json dist-newstyle/cache/plan.json
36+ --cabal-project cabal.project
37+```
38+
39+This will produce a `pkgs.nix` file that looks like the following:
40+
41+```nix
42+{
43+ pkgs = hackage:
44+ {
45+ packages = {
46+ "o-clock" = hackage.o-clock."0.1.1".revisions.default;
47+ ...
48+ };
49+ compiler = { ... };
50+ };
51+
52+ extras = hackage:
53+ { packages = { my-package = ./.plan.nix/my-package.nix; }; };
54+}
55+```
56+
57+It has converted Cabal's build plan into a Nix expression that selects
58+dependencies from `hackage.nix`. All local packages in the project are
59+generated with `cabal-to-nix` and added to the package set
60+description.
61+
62+## Creating the package set
63+
64+Import the generated `pkgs.nix` and pass to
65+[`mkCabalPkgSet`](../reference/library.md#mkcabalprojectpkgset) to
66+instantiate a package set.
67+
68+```nix
69+# default.nix
70+let
71+ # Import the Haskell.nix library,
72+ haskell = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {};
73+
74+ # Instantiate a package set using the generated file.
75+ pkgSet = haskell.mkCabalProjectPkgSet {
76+ plan-pkgs = import ./pkgs.nix;
77+ pkg-def-extras = [];
78+ modules = [];
79+ };
80+in
81+ pkgSet.config.hsPkgs
82+```
docs/user-guide/cross-compilation.mdnew file+105
@@ -0,0 +1,105 @@
1+Cross compilation of Haskell projects involves building a version of
2+GHC that outputs code for the target platform, and providing builds of
3+all library dependencies for that platform.
4+
5+First, understand how to cross-compile a normal package from
6+Nixpkgs. Matthew Bauer's [Beginners' guide to cross compilation in
7+Nixpkgs][bauer] is a useful resource.
8+
9+[bauer]: https://matthewbauer.us/blog/beginners-guide-to-cross.html
10+
11+
12+Using an example from the guide, this builds GNU Hello for a Raspberry
13+Pi:
14+
15+ nix build -f '<nixpkgs>' pkgsCross.raspberryPi.hello
16+
17+We will use the same principle in [Haskell.nix][] — replacing the normal
18+package set `pkgs` with a cross-compiling package set
19+`pkgsCross.raspberryPi`.
20+
21+### Raspberry Pi example
22+
23+This is an example of using [Haskell.nix][] to build the [Bench][]
24+command-line utility, which is a Haskell program.
25+
26+```nix
27+{ pkgs ? import <nixpkgs> {} }:
28+let
29+ haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz);
30+ native = haskellNix { inherit pkgs; };
31+in
32+ native.haskellPackages.bench.components.exes.bench
33+```
34+
35+Now switch the package set as in the previous example:
36+
37+```nix
38+{ pkgs ? import <nixpkgs> {} }:
39+let
40+ haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz);
41+ raspberryPi = haskellNix { pkgs = pkgs.pkgsCross.raspberryPi; };
42+in
43+ raspberryPi.haskellPackages.bench.components.exes.bench
44+```
45+
46+You should be prepared for a long wait because it first needs to build
47+GHC, before building all the Haskell dependencies of [Bench][]. If all
48+of these dependencies compiled successfully, I would be very surprised!
49+
50+To fix the build problems, you must add extra configuration to the
51+package set. Your project will have a [`mkStackPkgSet`](../reference/library.md#mkstackpkgset) or
52+[`mkCabalProjectPkgSet`](../reference/library.md#mkcabalprojectpkgset). It is there where you must add
53+[module options](../reference/modules.md) for setting compiler flags and so on.
54+
55+### Static executables with Musl libc
56+
57+Another application of cross-compiling is to produce fully static
58+binaries for Linux. For information about how to do that with the
59+[Nixpkgs Haskell infrastructure][nixpkgs] (not [Haskell.nix][]), see
60+[nh2/static‑haskell‑nix][nh2]. Vaibhav Sagar's linked [blog
61+post][vaibhav] is also very informative.
62+
63+
64+```nix
65+{ pkgs ? import <nixpkgs> {} }:
66+let
67+ haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz);
68+ musl64 = haskellNix { pkgs = pkgs.pkgsCross.musl64; };
69+in
70+ musl64.haskellPackages.bench.components.exes.bench
71+```
72+
73+This example will build [Bench][] linked against Musl libc. However
74+the executable will still be dynamically linked. To get fully static
75+executables you must add package overrides to:
76+
77+1. Disable dynamic linking
78+2. Provide static versions of system libraries. (For more details, see
79+ [Vaibhav's article][vaibhav]).
80+
81+```nix
82+{
83+ packages.bench.components.exes.bench.configureFlags =
84+ stdenv.lib.optionals stdenv.hostPlatform.isMusl [
85+ "--disable-executable-dynamic"
86+ "--disable-shared"
87+ "--ghc-option=-optl=-pthread"
88+ "--ghc-option=-optl=-static"
89+ "--ghc-option=-optl=-L${gmp6.override { withStatic = true; }}/lib"
90+ "--ghc-option=-optl=-L${zlib.static}/lib"
91+ ];
92+}
93+```
94+
95+!!! note "Licensing"
96+ Note that if copyleft licensing your program is a problem for you,
97+ then you need to statically link with `integer-simple` rather than
98+ `integer-gmp`. However, at present, [Haskell.nix][] does not provide
99+ an option for this.
100+
101+[nh2]: https://github.com/nh2/static-haskell-nix
102+[vaibhav]: https://vaibhavsagar.com/blog/2018/01/03/static-haskell-nix/
103+[haskell.nix]: https://github.com/input-output-hk/haskell.nix
104+[bench]: https://hackage.haskell.org/package/bench
105+[nixpkgs]: https://nixos.org/nixpkgs/manual/#users-guide-to-the-haskell-infrastructure
docs/user-guide/development.mdnew file+144
@@ -0,0 +1,144 @@
1+Haskell.nix also provides reproducible development environments for
2+your Haskell projects. These environments can contain not only GHC and
3+your Haskell package dependencies, but also the required system
4+libraries and build tools.
5+
6+Inside the development shell, you can run commands such as `ghc`,
7+`ghci`, or `cabal new‑build`, and they will have all dependencies
8+available.
9+
10+Every dependency will be cached in your Nix store. If you have set up
11+Hydra CI, then your team can share pre-built dependencies.
12+
13+These examples assume that you have created your package set as
14+described in [Creating Nix builds for your projects](projects.md) and
15+it exists in a file called `default.nix`.
16+
17+!!! note
18+
19+ Old-style `cabal build` and `stack` builds are not (yet)
20+ supported. For example, `stack` will (by design) download and
21+ rebuild all dependencies, even though they are available in the
22+ shell. However, if you have a Stack project, you can generate the
23+ package set with Haskell.nix, then use `cabal new‑build` to work
24+ on it.
25+
26+## How to get a development shell for a package
27+
28+Run a `nix‑shell` on `components.all` of your package. `all` is a
29+synthetic component whose dependencies are the union of the
30+dependencies of all components in the package. Therefore, you will be
31+able to build the test suites because their dependencies will be
32+included.
33+
34+```nix
35+# shell.nix
36+let
37+ hsPkgs = import ./default.nix {};
38+in
39+ hsPkgs.my-package.components.all
40+```
41+
42+## How to get a development shell for a multi-package project
43+
44+If you have a Cabal or Stack project with multiple packages
45+(i.e. multiple `.cabal` files, not a single package with multiple
46+components), then you will need a development environment that
47+contains the _dependencies_ of your packages, but not the packages
48+themselves. This is what the `shellFor` function does.
49+
50+```nix
51+# shell.nix
52+{ pkgs ? import <nixpkgs> {} };
53+
54+let
55+ hsPkgs = import ./default.nix { inherit pkgs; };
56+in
57+ hsPkgs.shellFor {
58+ # Include only the *local* packages of your project.
59+ packages = ps: with ps; [
60+ pkga
61+ pkgb
62+ ];
63+
64+ # Builds a Hoogle documentation index of all dependencies,
65+ # and provides a "hoogle" command to search the index.
66+ withHoogle = true;
67+
68+ # You might want some extra tools in the shell (optional).
69+ buildInputs = with pkgs.haskellPackages;
70+ [ hlint stylish-haskell ghcid ];
71+ }
72+```
73+
74+## How to get an ad-hoc development shell including certain packages
75+
76+This creates a development environment with the given packages
77+registered in the package database. The `ghcWithPackages` function
78+operates on a Haskell.nix package set, and accepts an argument that
79+selects packages from the larger package set.
80+
81+```nix
82+# shell.nix
83+let
84+ haskell = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {};
85+in
86+ haskell.haskellPackages.ghcWithPackages (ps: with ps;
87+ [ lens conduit conduit-extra ])
88+```
89+
90+If you need a Hoogle documentation index, use `ghcWithHoogle` in place
91+of `ghcWithPackages`.
92+
93+## How to get packages from a certain Stackage snapshot
94+
95+Haskell.nix knows about every released Stackage snapshot. You can use
96+it to build packages from a given snapshot, without setting up a full
97+project.
98+
99+```nix
100+let
101+ haskell = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {};
102+in
103+ haskell.snapshots."lts-13.18".alex.components.exes.alex
104+```
105+
106+There are Haskell.nix package sets for every Stackage snaphot under
107+`haskell.snapshots`.
108+
109+The alias `haskell.haskellPackages` corresponds to the package set for
110+a recent LTS Haskell version.
111+
112+You can use `ghcWithPackages` on any of these package sets to quickly
113+get a shell with some packages.
114+
115+!!! warning
116+ The build will not work if your Nixpkgs does not contain the version
117+ of GHC specified in the snapshot. Nixpkgs only carries the
118+ latest version of each recent release series, so many snapshots
119+ can't be built.
120+
121+
122+## Emacs IDE support
123+
124+Once you have a development shell, then you can begin configuring
125+Emacs to use it. The way I do it is:
126+
127+1. Run [lorri watch](https://github.com/target/lorri) to continously
128+ build the shell environment and maintain GC roots.
129+
130+2. Use [emacs‑direnv](https://github.com/wbolster/emacs-direnv) to
131+ push the development environment into Emacs.
132+
133+3. Use [Dante](https://github.com/jyp/dante) for highlighting errors
134+ and auto-completion. You must customize Dante to prevent it from
135+ automatically using `nix‑shell` or `stack`. Trim `dante‑methods` to
136+ just `new‑build` and `bare‑ghci`.
137+
138+ You can also use [`.dir‑locals.el`](https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html)
139+ for this. If your project has multiple targets, set `dante‑target`
140+ per-directory.
141+
142+4. For [`haskell‑mode`](https://github.com/haskell/haskell-mode)
143+ interactive Haskell, set `haskell‑process‑type` to
144+ `cabal‑new‑repl`.
docs/user-guide/projects.mdnew file+61
@@ -0,0 +1,61 @@
1+# How to create Nix builds for your own private Haskell packages
2+
3+The general structure will be the same, independent of the use of
4+Stack or Cabal.
5+
6+Let us assume for now that we have already generated a `pkgs.nix`
7+expression. The following file then produces a package set:
8+
9+```nix
10+# default.nix
11+let
12+ # Import the Haskell.nix library,
13+ haskell = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {};
14+
15+ # Import the file you will create in the stack-to-nix or cabal-to-nix step.
16+ my-pkgs = import ./pkgs.nix;
17+
18+ # Stack projects use this:
19+ pkgSet = haskell.mkStackPkgSet {
20+ stack-pkgs = my-pkgs;
21+ pkg-def-overlays = [
22+ # these extras will provide additional packages
23+ # ontop of the package set. E.g. extra-deps
24+ # for stack packages. or local packages for
25+ # cabal.projects
26+ ];
27+ modules = [
28+ # specific package overrides would go here
29+ # example:
30+ # packages.cbors.patches = [ ./one.patch ];
31+ # packages.cbors.flags.optimize-gmp = false;
32+ ];
33+ };
34+
35+ # Cabal projects use this:
36+ pkgSet = haskell.mkCabalProjectPkgSet {
37+ plan-pkgs = my-pkgs;
38+ pkg-def-extras = [];
39+ modules = [];
40+ };
41+
42+in pkgSet.config.hsPkgs // { _config = pkgSet.config; }
43+```
44+
45+With this setup you can then start building the components of
46+interest:
47+
48+```bash
49+nix build -f default.nix $pkg.components.library
50+```
51+
52+to build the library for `$pkg` or
53+
54+```bash
55+nix build -f default.nix $pkg.components.exes.$exe
56+```
57+
58+to build a specific executable. The same holds for test suites and benchmarks.
59+
60+- [Generating a `pkgs.nix` for a Stack project](./stack-projects.md)
61+- [Generating a `pkgs.nix` for a Cabal project](./cabal-projects.md)
docs/user-guide/stack-projects.mdnew file+56
@@ -0,0 +1,56 @@
1+Here we will look into how to generate the `pkgs.nix` file for a
2+`stack.yaml` project. For the full integration see the
3+[previous page](./projects.md).
4+
5+## Using `stack-to-nix`
6+
7+With [nix-tools installed](../user-guide.md), we can simply run the
8+following command on a stack project:
9+
10+```bash
11+stack-to-nix --output . --stack-yaml stack.yaml
12+```
13+
14+This will produce a `pkgs.nix` file that looks like the following:
15+```nix
16+{
17+ resolver = "lts-12.17";
18+ extras = hackage:
19+ {
20+ packages = {
21+ "o-clock" = hackage.o-clock."0.1.1".revisions.default;
22+ ...
23+ } // {
24+ my-package = ./my-package.nix;
25+ ...
26+ };
27+ };
28+}
29+```
30+
31+This file contains the stackage resolver, as well as set of extra
32+packages. The extras specifies which `extra-deps` (here:
33+`o-clock-0.1.1`) we wanted to add over the stackage snapshot, and what
34+local packages we want (here: `my-package`).
35+
36+## Creating the package set
37+
38+Import the generated `pkgs.nix` and pass to
39+[`mkStackPkgSet`](../reference/library.md#mkstackpkgset) to
40+instantiate a package set.
41+
42+```nix
43+# default.nix
44+let
45+ # Import the Haskell.nix library,
46+ haskell = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {};
47+
48+ # Instantiate a package set using the generated file.
49+ pkgSet = haskell.mkStackPkgSet {
50+ stack-pkgs = import ./pkgs.nix;
51+ pkg-def-overlays = [];
52+ modules = [];
53+ };
54+in
55+ pkgSet.config.hsPkgs
56+```
mkdocs.yml+15−2
@@ -13,6 +13,11 @@ site_name: Alternative Haskell Infrastructure for Nixpkgs
1313theme: readthedocs
1414site_url: null
1515repo_url: https://github.com/input-output-hk/haskell.nix
16+permalink: true
17+markdown_extensions:
18+ - admonition
19+ - toc:
20+ permalink: true
1621
1722# this is called `nav` in more recent mkdocs versions. Mine
1823# right now is 0.17.5
@@ -21,11 +26,19 @@ pages:
2126 - 'Architecture': architecture.md
2227 - 'User Guide':
2328 - 'General': user-guide.md
24− - 'Stack Projects': user-guide-stack.md
25− - 'Cabal Proejcts': user-guide-cabal.md
29+ - 'Creating Nix builds for your projects': user-guide/projects.md
30+ - 'Stack Projects': user-guide/stack-projects.md
31+ - 'Cabal Projects': user-guide/cabal-projects.md
32+ - 'How to create a development environment': user-guide/development.md
33+ - 'How to cross-compile your project': user-guide/cross-compilation.md
34+ - 'Reference':
35+ - 'Command-line tools': reference/commands.md
36+ - 'Haskell.nix Libary': reference/library.md
37+ - 'Module options': reference/modules.md
2638 - 'Templates / Abstraction':
2739 - 'IOHKs nix library': iohk-nix.md
2840 - 'Dev Notes':
2941 - 'Architecture': dev-architecture.md
3042 - 'Removing withPackage wrapper': removing-with-package-wrapper.md
3143 - 'Maintainer Scripts': maintainer-scripts.md
44+ - 'ChangeLog': changelog.md