on 9d4cb21 help sign in
haskell.nix/docs/user-guide.md
282 lines 10.0 kB history raw
1# User Guide
3[Haskell.nix][] can be use for two different use cases:
5### Use 1 : to build a specific package from hackage or a [stackage][] lts or nightly set.
7To build a package, say [lens][], from a stackage snapshot, say [lts-13.28][],
8you could run
9```bash
10nix build '(with import <nixpkgs> (import ./.); haskell-nix.snapshots."lts-13.28").lens.components.library'
11```
12which would build the [lens][] library component from the lens package as fixed
13by the [lts-13.28][] stackage snapshot.
15To build any package from hackage, say [lens][], in version, say 4.17.1, you
16could run
17```bash
18nix build '(with import <nixpkgs> (import ./.); (haskell-nix.hackage-package { name = "lens"; version = "4.17.1"; })).components.library'
19```
20which would build the [lens][] library component from the [lens-4.17.1][] package
21from hackage. The dependencies would be solved against the most recent
22[hackage-index-state][] that comes via the [hackage.nix][] pin with your
23[haskell.nix][] checkout. A specific one can be specified as well:
24```bash
25nix build '(with import <nixpkgs> (import ./.); (haskell-nix.hackage-package { name = "lens"; version = "4.17.1"; index-state = "2019-07-14T00:00:00Z"; })).components.library'
26```
27which would use the hackage index as of `2019-07-14T00:00:00Z` to produce a build plan
28for the [lens-4.17.1][] package.
31### Use 2 : to build a stack or cabal project.
33So you want to use [Haskell.nix][] with your stack or cabal project. The
34general approach will be to pick the right tool from `nix-tools` and
35produce a `pkgs.nix` expression. Getting a copy of the `nix-tools`
36(and potentially the [Haskell.nix][] source), will then equip us to
37produce derivations that we can `nix build`.
39[haskell.nix]: https://github.com/input-output-hk/haskell.nix
40[stackage]: https://stackage.org
41[lts-13.28]: https://www.stackage.org/lts-13.28
42[lens]: https://hackage.haskell.org/package/lens
43[lens-4.17.1]: https://hackage.haskell.org/package/lens-4.17.1
44[hackage.nix]: https://github.com/input-output-hk/hackage.nix
45[hackage-index-state]: https://github.com/input-output-hk/hackage.nix/blob/master/index-state-hashes.nix
47## Installing `nix-tools`
49To build the latest `nix-tools` and store the result at `./nt`, run:
51```bash
52nix build '(with import <nixpkgs> (import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz)); haskell-nix.nix-tools)' --out-link nt
53```
55If you would like to then install `nix-tools` into your profile, run:
57```bash
58nix-env -i ./nt
59```
61## Getting the [Haskell.nix][] source (optional)
63The [Haskell.nix][] and `nix-tools` source will be useful if you would
64like to contribute improvements, or read the source code to fully
65understand something that the documentation doesn't cover.
67```bash
68git clone https://github.com/input-output-hk/nix-tools
69git clone https://github.com/input-output-hk/haskell.nix
70cd haskell.nix
71nix build -f . haskell-nix.nix-tools --out-link nt
72```
74## Using [Haskell.nix][] with your project
76The easiest way to get a hold of [Haskell.nix][] is with
77[`fetchTarball`](https://nixos.org/nix/manual/#ssec-builtins).
79```nix
80import <nixpkgs> (import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz))
81```
83### Using your cabal.project file
85If your project has a `cabal.project` you can add a `default.nix` like this:
87```nix
88{ pkgs ? import <nixpkgs> (import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz))
89, haskellCompiler ? "ghc865"
90}:
91 pkgs.haskell-nix.cabalProject {
92 src = pkgs.haskell-nix.haskellLib.cleanGit { src = ./.; };
93 ghc = pkgs.buildPackages.pkgs.haskell.compiler.${haskellCompiler};
94 # pkg-def-extras = [
95 # # Additional packages ontop of all those listed in `cabal.project`
96 # ];
97 # modules = [
98 # # Specific package overrides would go here for example:
99 # packages.cbors.package.ghcOptions = "-Werror";
100 # packages.cbors.patches = [ ./one.patch ];
101 # packages.cbors.flags.optimize-gmp = false;
102 # # It may be better to set flags in `cabal.project` instead
103 # # (`plan-to-nix` will include them as defaults).
104 # ];
105 }
106```
108Note: The `cleanGit` call will exclude any files not in the index file
109in the local `.git` directory. This is extremely useful as it avoids
110unwanted builds (for instance when the contents of `dist-newstyle` are
111modified by cabal).
113You can build a component from your project with `nix-build` (in this
114case the `hello` executable in a `helloworld` package):
116```bash
117nix-build -A helloworld.components.exes.hello
118```
120For interactive development you can run:
122```bash
123nix-shell -A shellFor
124```
126The resulting shell will include all the dependencies of the local packages
127listed in your `cabal.project` file (but it will not build those local
128packages).
130Inside the shell use `cabal new-build` and `cabal new-repl` to work on the
131cabal project as you normally would. They will use the packages provided
132by nix whenever possible.
134It is a good idea to add `write-ghc-environment-files: never` to your
135`cabal.project` file to prevent unwanted `.ghc.environment.*` files
136(they will prevent subsequent `nix-shell` invocations from working
137properly).
139Adding an `index-state` to your `cabal.project` can pin the plan used so that
140the same packages will be built each time (until you change the index-state
141or one of the constraints in your local `.cabal` files).
143### Using your stack.yaml file
145If your project has a `stack.yaml` you can add a `default.nix` like this:
147```nix
148{ pkgs ? import <nixpkgs> (import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz))
149}:
150 pkgs.haskell-nix.stackProject {
151 src = pkgs.haskell-nix.haskellLib.cleanGit { src = ./.; };
152 # pkg-def-extras = [
153 # # Additional packages ontop of all those listed in `stack.yaml`
154 # ];
155 # modules = [
156 # # Specific package overrides would go here for example:
157 # packages.cbors.package.ghcOptions = "-Werror";
158 # packages.cbors.patches = [ ./one.patch ];
159 # packages.cbors.flags.optimize-gmp = false;
160 # # It may be better to set flags in `stack.yaml` instead
161 # # (`stack-to-nix` will include them as defaults).
162 # ];
163 }
164```
166You can build a component from your project with `nix-build` (in this
167case the `hello` executable in a `helloworld` package):
169```bash
170nix-build -A helloworld.components.exes.hello
171```
173### Pinning the [Haskell.nix][] version
175For simplicity's sake we will use `fetchTarball` for the examples in
176this documentation. This will always get the latest version, and is
177similar to an auto-updating Nix channel.
179However, in your own project, you may wish to pin [Haskell.nix][] (as
180you would pin Nixpkgs). This will make your builds reproducable, more
181predictable, and faster (because the fixed version is cached).
183One way of doing this is to use `nix-prefetch-git` to get a JSON file
184with a revision and SHA-256 hash of [Haskell.nix][].
186```
187$ nix-prefetch-git --quiet https://github.com/input-output-hk/haskell.nix | tee haskell-nix-src.json
189 "url": "https://github.com/input-output-hk/haskell.nix",
190 "rev": "f1a94a4c82a2ab999a67c3b84269da78d89f0075",
191 "date": "2019-06-05T01:06:12+00:00",
192 "sha256": "0ggxsppjlb6q6a83y12cwgrdnqnw1s128rpibgzs5p1966bdfqla",
193 "fetchSubmodules": false
195```
197(The `tee` command is just to show you the result.)
198Use the following expression to import that version:
200```nix
201{ nixpkgs ? <nixpkgs> }:
203let
204 spec = builtins.fromJSON (builtins.readFile ./haskell-nix-src.json);
205 haskell-nix-src = (import nixpkgs {}).fetchgit {
206 name = "haskell-lib";
207 inherit (spec) url rev sha256 fetchSubmodules;
208 };
209in
210 import nixpkgs (import haskell-nix-src)
211```
213There are other possible schemes for pinning. See
214[`haskell.nix/lib/fetch-external.nix`](https://github.com/input-output-hk/haskell.nix/blob/master/lib/fetch-external.nix),
215the [niv](https://github.com/nmattia/niv) tool, or the Nix Flakes
216proposal.
218### Overriding the Hackage version
220Sometimes you might want to use a chosen version of Haskell.nix with a
221recent update of Hackage or Stackage. This can be done with JSON pins:
223```bash
224nix-prefetch-git https://github.com/input-output-hk/hackage.nix | tee hackage-src.json
225nix-prefetch-git https://github.com/input-output-hk/stackage.nix | tee stackage-src.json
226```
228The resulting JSON files will correspond to the latest revision of
229[hackage.nix][] and [stackage.nix][]. See
230[Architecture](architecture.md) for more information about how
231these Git repositories correspond to the actual Hackage and Stackage.
233[hackage.nix]: https://github.com/input-output-hk/hackage.nix
234[stackage.nix]: https://github.com/input-output-hk/stackage.nix
236```nix
237{ pkgs ? import <nixpkgs> (haskellNixArgs // { overlays = haskellNixArgs.overlays ++ [
238 (self: super: {
239 haskell-nix = super.haskell-nix // {
240 hackageSourceJSON = ./hackage-src.json;
241 stackageSourceJSON = ./stackage-src.json;
242 };
243 })]; })
244, haskellNixArgs ? import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz)
245}:
246 pkgs
247```
249## Using `nix repl`
251It's sometimes useful to load [Haskell.nix][] in the REPL to explore
252attrsets and try examples.
254```
255# example.nix
256{ nixpkgs ? <nixpkgs> }:
257rec {
258 haskell = import nixpkgs (import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz));
259 pkgNames = haskell.pkgs.lib.attrNames haskell.haskell-nix.snapshots."lts-13.18";
261```
263Load the example file:
265```
266$ nix repl '<nixpkgs>' example.nix
267Welcome to Nix version 2.3pre6631_e58a7144. Type :? for help.
269Loading '<nixpkgs>'...
270Added 10403 variables.
272Loading 'example2.nix'...
273Added 2 variables.
275nix-repl> lib.take 5 pkgNames
276[ "ALUT" "ANum" "Allure" "Boolean" "BoundedChan" ]
278nix-repl>
279```
281Now that you have `nix-tools` and are able to import [Haskell.nix][],
282you can continue to the next chapter.