on edd1d21 help sign in
haskell.nix/docs/user-guide/development.md
181 lines 6.0 kB history raw
1Haskell.nix also provides reproducible development environments for
2your Haskell projects. These environments can contain not only GHC and
3your Haskell package dependencies, but also the required system
4libraries and build tools.
6Inside the development shell, you can run commands such as `ghc`,
7`ghci`, or `cabal new‑build`, and they will have all dependencies
8available.
10Every dependency will be cached in your Nix store. If you have set up
11Hydra CI, then your team can share pre-built dependencies.
13These examples assume that you have created your package set as
14described in [Creating Nix builds for your projects](projects.md) and
15it exists in a file called `default.nix`.
17!!! note
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.
26## How to get a development shell for a package
28Run a `nix‑shell` on `components.all` of your package. `all` is a
29synthetic component whose dependencies are the union of the
30dependencies of all components in the package. Therefore, you will be
31able to build the test suites because their dependencies will be
32included.
34```nix
35# shell.nix
36let
37 hsPkgs = import ./default.nix {};
38in
39 hsPkgs.my-package.components.all
40```
42## How to get a development shell for a multi-package project
44If you have a Cabal or Stack project with multiple packages
45(i.e. multiple `.cabal` files, not a single package with multiple
46components), then you will need a development environment that
47contains the _dependencies_ of your packages, but not the packages
48themselves. This is what the [`shellFor`][shellFor] function does.
50```nix
51# shell.nix
52{ pkgs ? import <nixpkgs> {} }:
54let
55 hsPkgs = import ./default.nix { inherit pkgs; };
56in
57 hsPkgs.shellFor {
58 # Include only the *local* packages of your project.
59 packages = ps: with ps; [
60 pkga
61 pkgb
62 ];
64 # Builds a Hoogle documentation index of all dependencies,
65 # and provides a "hoogle" command to search the index.
66 withHoogle = true;
68 # You might want some extra tools in the shell (optional).
70 # Some common tools can be added with the `tools` argument
71 tools = { cabal = "3.2.0.0"; hlint = "2.2.11"; };
72 # See overlays/tools.nix for more details
74 # Some you may need to get some other way.
75 buildInputs = with pkgs.haskellPackages;
76 [ ghcid ];
78 # Prevents cabal from choosing alternate plans, so that
79 # *all* dependencies are provided by Nix.
80 exactDeps = true;
81 }
82```
84See also: [Haskell.nix Library Reference: `shellFor`][shellFor]
86[shellFor]: ../reference/library.md#shellfor
88## How to get a local Hoogle index
90If you need a local Hoogle for all the dependencies of your project create this file
92```nix
93# shell-hoogle.nix
94let
95 hsPkgs = import ./default.nix {};
96in
97 hsPkgs.shellFor {
98 packages = ps: [ps.my-package];
99 withHoogle = true;
100 }
101```
103and run `nix-shell shell-hoogle.nix --run "hoogle server --local"`.
104This will open a local Hoogle server at `http://127.0.0.1:8080`.
107## How to get an ad-hoc development shell including certain packages
109This creates a development environment with the given packages
110registered in the package database. The `ghcWithPackages` function
111operates on a Haskell.nix package set, and accepts an argument that
112selects packages from the larger package set.
114```nix
115# shell.nix
116let
117 haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {};
118 nixpkgs = import haskellNix.sources.nixpkgs-1909 haskellNix.nixpkgsArgs;
119 haskell = nixpkgs.haskell-nix;
120in
121 haskell.haskellPackages.ghcWithPackages (ps: with ps;
122 [ lens conduit conduit-extra ])
123```
125If you need a Hoogle documentation index, use `ghcWithHoogle` in place
126of `ghcWithPackages`.
128## How to get packages from a certain Stackage snapshot
130Haskell.nix knows about every released Stackage snapshot. You can use
131it to build packages from a given snapshot, without setting up a full
132project.
134```nix
135let
136 haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {};
137 nixpkgs = import haskellNix.sources.nixpkgs-1909 haskellNix.nixpkgsArgs;
138 haskell = nixpkgs.haskell-nix;
139in
140 haskell.snapshots."lts-13.18".alex.components.exes.alex
141```
143There are Haskell.nix package sets for every Stackage snaphot under
144`haskell.snapshots`.
146The alias `haskell.haskellPackages` corresponds to the package set for
147a recent LTS Haskell version.
149You can use `ghcWithPackages` on any of these package sets to quickly
150get a shell with some packages.
152!!! warning
153 The build will not work if your Nixpkgs does not contain the version
154 of GHC specified in the snapshot. Nixpkgs only carries the
155 latest version of each recent release series, so many snapshots
156 can't be built.
159## Emacs IDE support
161Once you have a development shell, then you can begin configuring
162Emacs to use it. The way I do it is:
1641. Run [lorri watch](https://github.com/target/lorri) to continously
165 build the shell environment and maintain GC roots.
1672. Use [emacs‑direnv](https://github.com/wbolster/emacs-direnv) to
168 push the development environment into Emacs.
1703. Use [Dante](https://github.com/jyp/dante) for highlighting errors
171 and auto-completion. You must customize Dante to prevent it from
172 automatically using `nix‑shell` or `stack`. Trim `dante‑methods` to
173 just `new‑build` and `bare‑ghci`.
175 You can also use [`.dir‑locals.el`](https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html)
176 for this. If your project has multiple targets, set `dante‑target`
177 per-directory.
1794. For [`haskell‑mode`](https://github.com/haskell/haskell-mode)
180 interactive Haskell, set `haskell‑process‑type` to
181 `cabal‑new‑repl`.