| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | --- | 
					
						
							|  |  |  |  | title: User's Guide for Haskell in Nixpkgs | 
					
						
							|  |  |  |  | author: Peter Simons | 
					
						
							|  |  |  |  | date: 2015-06-01 | 
					
						
							|  |  |  |  | --- | 
					
						
							| 
									
										
										
										
											2016-05-22 11:31:08 +01:00
										 |  |  |  | # User's Guide to the Haskell Infrastructure
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | ## How to install Haskell packages
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Nixpkgs distributes build instructions for all Haskell packages registered on | 
					
						
							|  |  |  |  | [Hackage](http://hackage.haskell.org/), but strangely enough normal Nix package | 
					
						
							|  |  |  |  | lookups don't seem to discover any of them, except for the default version of ghc, cabal-install, and stack: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | $ nix-env -i alex | 
					
						
							|  |  |  |  | error: selector ‘alex’ matches no derivations | 
					
						
							|  |  |  |  | $ nix-env -qa ghc | 
					
						
							|  |  |  |  | ghc-7.10.2 | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | The Haskell package set is not registered in the top-level namespace because it | 
					
						
							|  |  |  |  | is *huge*. If all Haskell packages were visible to these commands, then | 
					
						
							|  |  |  |  | name-based search/install operations would be much slower than they are now. We | 
					
						
							|  |  |  |  | avoided that by keeping all Haskell-related packages in a separate attribute | 
					
						
							|  |  |  |  | set called `haskellPackages`, which the following command will list: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | $ nix-env -f "<nixpkgs>" -qaP -A haskellPackages | 
					
						
							|  |  |  |  | haskellPackages.a50         a50-0.5 | 
					
						
							|  |  |  |  | haskellPackages.abacate     haskell-abacate-0.0.0.0 | 
					
						
							|  |  |  |  | haskellPackages.abcBridge   haskell-abcBridge-0.12 | 
					
						
							|  |  |  |  | haskellPackages.afv         afv-0.1.1 | 
					
						
							|  |  |  |  | haskellPackages.alex        alex-3.1.4 | 
					
						
							|  |  |  |  | haskellPackages.Allure      Allure-0.4.101.1 | 
					
						
							|  |  |  |  | haskellPackages.alms        alms-0.6.7 | 
					
						
							|  |  |  |  | [... some 8000 entries omitted  ...] | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | To install any of those packages into your profile, refer to them by their | 
					
						
							|  |  |  |  | attribute path (first column): | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-env -f "<nixpkgs>" -iA haskellPackages.Allure ... | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | The attribute path of any Haskell packages corresponds to the name of that | 
					
						
							|  |  |  |  | particular package on Hackage: the package `cabal-install` has the attribute | 
					
						
							|  |  |  |  | `haskellPackages.cabal-install`, and so on. (Actually, this convention causes | 
					
						
							|  |  |  |  | trouble with packages like `3dmodels` and `4Blocks`, because these names are | 
					
						
							|  |  |  |  | invalid identifiers in the Nix language. The issue of how to deal with these | 
					
						
							|  |  |  |  | rare corner cases is currently unresolved.) | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-27 22:23:45 -05:00
										 |  |  |  | Haskell packages whose Nix name (second column) begins with a `haskell-` prefix | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | are packages that provide a library whereas packages without that prefix | 
					
						
							|  |  |  |  | provide just executables. Libraries may provide executables too, though: the | 
					
						
							|  |  |  |  | package `haskell-pandoc`, for example, installs both a library and an | 
					
						
							|  |  |  |  | application. You can install and use Haskell executables just like any other | 
					
						
							|  |  |  |  | program in Nixpkgs, but using Haskell libraries for development is a bit | 
					
						
							|  |  |  |  | trickier and we'll address that subject in great detail in section [How to | 
					
						
							|  |  |  |  | create a development environment]. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Attribute paths are deterministic inside of Nixpkgs, but the path necessary to | 
					
						
							|  |  |  |  | reach Nixpkgs varies from system to system. We dodged that problem by giving | 
					
						
							|  |  |  |  | `nix-env` an explicit `-f "<nixpkgs>"` parameter, but if you call `nix-env` | 
					
						
							|  |  |  |  | without that flag, then chances are the invocation fails: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | $ nix-env -iA haskellPackages.cabal-install | 
					
						
							|  |  |  |  | error: attribute ‘haskellPackages’ in selection path | 
					
						
							|  |  |  |  |        ‘haskellPackages.cabal-install’ not found | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | On NixOS, for example, Nixpkgs does *not* exist in the top-level namespace by | 
					
						
							|  |  |  |  | default. To figure out the proper attribute path, it's easiest to query for the | 
					
						
							|  |  |  |  | path of a well-known Nixpkgs package, i.e.: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | $ nix-env -qaP coreutils | 
					
						
							|  |  |  |  | nixos.coreutils  coreutils-8.23 | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | If your system responds like that (most NixOS installations will), then the | 
					
						
							|  |  |  |  | attribute path to `haskellPackages` is `nixos.haskellPackages`. Thus, if you | 
					
						
							|  |  |  |  | want to use `nix-env` without giving an explicit `-f` flag, then that's the way | 
					
						
							|  |  |  |  | to do it: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-env -qaP -A nixos.haskellPackages | 
					
						
							|  |  |  |  | nix-env -iA nixos.haskellPackages.cabal-install | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Our current default compiler is GHC 7.10.x and the `haskellPackages` set | 
					
						
							|  |  |  |  | contains packages built with that particular version. Nixpkgs contains the | 
					
						
							|  |  |  |  | latest major release of every GHC since 6.10.4, however, and there is a whole | 
					
						
							|  |  |  |  | family of package sets available that defines Hackage packages built with each | 
					
						
							|  |  |  |  | of those compilers, too: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-env -f "<nixpkgs>" -qaP -A haskell.packages.ghc6123 | 
					
						
							|  |  |  |  | nix-env -f "<nixpkgs>" -qaP -A haskell.packages.ghc763 | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | The name `haskellPackages` is really just a synonym for | 
					
						
							|  |  |  |  | `haskell.packages.ghc7102`, because we prefer that package set internally and | 
					
						
							|  |  |  |  | recommend it to our users as their default choice, but ultimately you are free | 
					
						
							|  |  |  |  | to compile your Haskell packages with any GHC version you please. The following | 
					
						
							|  |  |  |  | command displays the complete list of available compilers: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | $ nix-env -f "<nixpkgs>" -qaP -A haskell.compiler | 
					
						
							|  |  |  |  | haskell.compiler.ghc6104        ghc-6.10.4 | 
					
						
							|  |  |  |  | haskell.compiler.ghc6123        ghc-6.12.3 | 
					
						
							|  |  |  |  | haskell.compiler.ghc704         ghc-7.0.4 | 
					
						
							|  |  |  |  | haskell.compiler.ghc722         ghc-7.2.2 | 
					
						
							|  |  |  |  | haskell.compiler.ghc742         ghc-7.4.2 | 
					
						
							|  |  |  |  | haskell.compiler.ghc763         ghc-7.6.3 | 
					
						
							|  |  |  |  | haskell.compiler.ghc784         ghc-7.8.4 | 
					
						
							|  |  |  |  | haskell.compiler.ghc7102        ghc-7.10.2 | 
					
						
							|  |  |  |  | haskell.compiler.ghcHEAD        ghc-7.11.20150402 | 
					
						
							|  |  |  |  | haskell.compiler.ghcNokinds     ghc-nokinds-7.11.20150704 | 
					
						
							|  |  |  |  | haskell.compiler.ghcjs          ghcjs-0.1.0 | 
					
						
							|  |  |  |  | haskell.compiler.jhc            jhc-0.8.2 | 
					
						
							|  |  |  |  | haskell.compiler.uhc            uhc-1.1.9.0 | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | We have no package sets for `jhc` or `uhc` yet, unfortunately, but for every | 
					
						
							|  |  |  |  | version of GHC listed above, there exists a package set based on that compiler. | 
					
						
							|  |  |  |  | Also, the attributes `haskell.compiler.ghcXYC` and | 
					
						
							|  |  |  |  | `haskell.packages.ghcXYC.ghc` are synonymous for the sake of convenience. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ## How to create a development environment
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ### How to install a compiler
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 21:09:16 +01:00
										 |  |  |  | A simple development environment consists of a Haskell compiler and one or both | 
					
						
							|  |  |  |  | of the tools `cabal-install` and `stack`. We saw in section | 
					
						
							|  |  |  |  | [How to install Haskell packages] how you can install those programs into your | 
					
						
							|  |  |  |  | user profile: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-env -f "<nixpkgs>" -iA haskellPackages.ghc haskellPackages.cabal-install | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Instead of the default package set `haskellPackages`, you can also use the more | 
					
						
							|  |  |  |  | precise name `haskell.compiler.ghc7102`, which has the advantage that it refers | 
					
						
							|  |  |  |  | to the same GHC version regardless of what Nixpkgs considers "default" at any | 
					
						
							|  |  |  |  | given time. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Once you've made those tools available in `$PATH`, it's possible to build | 
					
						
							|  |  |  |  | Hackage packages the same way people without access to Nix do it all the time: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | cabal get lens-4.11 && cd lens-4.11 | 
					
						
							|  |  |  |  | cabal install -j --dependencies-only | 
					
						
							|  |  |  |  | cabal configure | 
					
						
							|  |  |  |  | cabal build | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | If you enjoy working with Cabal sandboxes, then that's entirely possible too: | 
					
						
							|  |  |  |  | just execute the command | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | cabal sandbox init | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | before installing the required dependencies. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The `nix-shell` utility makes it easy to switch to a different compiler | 
					
						
							|  |  |  |  | version; just enter the Nix shell environment with the command | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-shell -p haskell.compiler.ghc784 | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-01-17 21:09:16 +01:00
										 |  |  |  | to bring GHC 7.8.4 into `$PATH`. Alternatively, you can use Stack instead of | 
					
						
							|  |  |  |  | `nix-shell` directly to select compiler versions and other build tools | 
					
						
							|  |  |  |  | per-project. It uses `nix-shell` under the hood when Nix support is turned on. | 
					
						
							|  |  |  |  | See [How to build a Haskell project using Stack]. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | If you're using `cabal-install`, re-running `cabal configure` inside the spawned | 
					
						
							|  |  |  |  | shell switches your build to use that compiler instead. If you're working on | 
					
						
							|  |  |  |  | a project that doesn't depend on any additional system libraries outside of GHC, | 
					
						
							|  |  |  |  | then it's even sufficient to just run the `cabal configure` command inside of | 
					
						
							|  |  |  |  | the shell: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-shell -p haskell.compiler.ghc784 --command "cabal configure" | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Afterwards, all other commands like `cabal build` work just fine in any shell | 
					
						
							|  |  |  |  | environment, because the configure phase recorded the absolute paths to all | 
					
						
							|  |  |  |  | required tools like GHC in its build configuration inside of the `dist/` | 
					
						
							|  |  |  |  | directory. Please note, however, that `nix-collect-garbage` can break such an | 
					
						
							|  |  |  |  | environment because the Nix store paths created by `nix-shell` aren't "alive" | 
					
						
							|  |  |  |  | anymore once `nix-shell` has terminated. If you find that your Haskell builds | 
					
						
							|  |  |  |  | no longer work after garbage collection, then you'll have to re-run `cabal | 
					
						
							|  |  |  |  | configure` inside of a new `nix-shell` environment. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ### How to install a compiler with libraries
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | GHC expects to find all installed libraries inside of its own `lib` directory. | 
					
						
							|  |  |  |  | This approach works fine on traditional Unix systems, but it doesn't work for | 
					
						
							|  |  |  |  | Nix, because GHC's store path is immutable once it's built. We cannot install | 
					
						
							|  |  |  |  | additional libraries into that location. As a consequence, our copies of GHC | 
					
						
							|  |  |  |  | don't know any packages except their own core libraries, like `base`, | 
					
						
							|  |  |  |  | `containers`, `Cabal`, etc. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | We can register additional libraries to GHC, however, using a special build | 
					
						
							|  |  |  |  | function called `ghcWithPackages`. That function expects one argument: a | 
					
						
							|  |  |  |  | function that maps from an attribute set of Haskell packages to a list of | 
					
						
							|  |  |  |  | packages, which determines the libraries known to that particular version of | 
					
						
							|  |  |  |  | GHC. For example, the Nix expression `ghcWithPackages (pkgs: [pkgs.mtl])` | 
					
						
							|  |  |  |  | generates a copy of GHC that has the `mtl` library registered in addition to | 
					
						
							|  |  |  |  | its normal core packages: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | $ nix-shell -p "haskellPackages.ghcWithPackages (pkgs: [pkgs.mtl])" | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | [nix-shell:~]$ ghc-pkg list mtl | 
					
						
							|  |  |  |  | /nix/store/zy79...-ghc-7.10.2/lib/ghc-7.10.2/package.conf.d: | 
					
						
							|  |  |  |  |     mtl-2.2.1 | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | This function allows users to define their own development environment by means | 
					
						
							| 
									
										
										
										
											2017-02-01 16:03:42 +01:00
										 |  |  |  | of an override. After adding the following snippet to `~/.config/nixpkgs/config.nix`, | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```nix | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   packageOverrides = super: let self = super.pkgs; in | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     myHaskellEnv = self.haskell.packages.ghc7102.ghcWithPackages | 
					
						
							|  |  |  |  |                      (haskellPackages: with haskellPackages; [ | 
					
						
							|  |  |  |  |                        # libraries | 
					
						
							|  |  |  |  |                        arrows async cgi criterion | 
					
						
							|  |  |  |  |                        # tools | 
					
						
							|  |  |  |  |                        cabal-install haskintex | 
					
						
							|  |  |  |  |                      ]); | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | it's possible to install that compiler with `nix-env -f "<nixpkgs>" -iA | 
					
						
							|  |  |  |  | myHaskellEnv`. If you'd like to switch that development environment to a | 
					
						
							|  |  |  |  | different version of GHC, just replace the `ghc7102` bit in the previous | 
					
						
							|  |  |  |  | definition with the appropriate name. Of course, it's also possible to define | 
					
						
							|  |  |  |  | any number of these development environments! (You can't install two of them | 
					
						
							|  |  |  |  | into the same profile at the same time, though, because that would result in | 
					
						
							|  |  |  |  | file conflicts.) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The generated `ghc` program is a wrapper script that re-directs the real | 
					
						
							|  |  |  |  | GHC executable to use a new `lib` directory --- one that we specifically | 
					
						
							|  |  |  |  | constructed to contain all those packages the user requested: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | $ cat $(type -p ghc) | 
					
						
							|  |  |  |  | #! /nix/store/xlxj...-bash-4.3-p33/bin/bash -e
 | 
					
						
							|  |  |  |  | export NIX_GHC=/nix/store/19sm...-ghc-7.10.2/bin/ghc | 
					
						
							|  |  |  |  | export NIX_GHCPKG=/nix/store/19sm...-ghc-7.10.2/bin/ghc-pkg | 
					
						
							|  |  |  |  | export NIX_GHC_DOCDIR=/nix/store/19sm...-ghc-7.10.2/share/doc/ghc/html | 
					
						
							|  |  |  |  | export NIX_GHC_LIBDIR=/nix/store/19sm...-ghc-7.10.2/lib/ghc-7.10.2 | 
					
						
							|  |  |  |  | exec /nix/store/j50p...-ghc-7.10.2/bin/ghc "-B$NIX_GHC_LIBDIR" "$@" | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | The variables `$NIX_GHC`, `$NIX_GHCPKG`, etc. point to the *new* store path | 
					
						
							|  |  |  |  | `ghcWithPackages` constructed specifically for this environment. The last line | 
					
						
							|  |  |  |  | of the wrapper script then executes the real `ghc`, but passes the path to the | 
					
						
							|  |  |  |  | new `lib` directory using GHC's `-B` flag. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The purpose of those environment variables is to work around an impurity in the | 
					
						
							|  |  |  |  | popular [ghc-paths](http://hackage.haskell.org/package/ghc-paths) library. That | 
					
						
							|  |  |  |  | library promises to give its users access to GHC's installation paths. Only, | 
					
						
							|  |  |  |  | the library can't possible know that path when it's compiled, because the path | 
					
						
							|  |  |  |  | GHC considers its own is determined only much later, when the user configures | 
					
						
							|  |  |  |  | it through `ghcWithPackages`. So we [patched | 
					
						
							| 
									
										
										
										
											2016-02-13 17:13:33 -08:00
										 |  |  |  | ghc-paths](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/patches/ghc-paths-nix.patch) | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | to return the paths found in those environment variables at run-time rather | 
					
						
							|  |  |  |  | than trying to guess them at compile-time. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | To make sure that mechanism works properly all the time, we recommend that you | 
					
						
							|  |  |  |  | set those variables to meaningful values in your shell environment, too, i.e. | 
					
						
							|  |  |  |  | by adding the following code to your `~/.bashrc`: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```bash | 
					
						
							|  |  |  |  | if type >/dev/null 2>&1 -p ghc; then | 
					
						
							|  |  |  |  |   eval "$(egrep ^export "$(type -p ghc)")" | 
					
						
							|  |  |  |  | fi | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | If you are certain that you'll use only one GHC environment which is located in | 
					
						
							|  |  |  |  | your user profile, then you can use the following code, too, which has the | 
					
						
							|  |  |  |  | advantage that it doesn't contain any paths from the Nix store, i.e. those | 
					
						
							|  |  |  |  | settings always remain valid even if a `nix-env -u` operation updates the GHC | 
					
						
							|  |  |  |  | environment in your profile: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```bash | 
					
						
							|  |  |  |  | if [ -e ~/.nix-profile/bin/ghc ]; then | 
					
						
							|  |  |  |  |   export NIX_GHC="$HOME/.nix-profile/bin/ghc" | 
					
						
							|  |  |  |  |   export NIX_GHCPKG="$HOME/.nix-profile/bin/ghc-pkg" | 
					
						
							|  |  |  |  |   export NIX_GHC_DOCDIR="$HOME/.nix-profile/share/doc/ghc/html" | 
					
						
							|  |  |  |  |   export NIX_GHC_LIBDIR="$HOME/.nix-profile/lib/ghc-$($NIX_GHC --numeric-version)" | 
					
						
							|  |  |  |  | fi | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ### How to install a compiler with libraries, hoogle and documentation indexes
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | If you plan to use your environment for interactive programming, not just | 
					
						
							|  |  |  |  | compiling random Haskell code, you might want to replace `ghcWithPackages` in | 
					
						
							|  |  |  |  | all the listings above with `ghcWithHoogle`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | This environment generator not only produces an environment with GHC and all | 
					
						
							|  |  |  |  | the specified libraries, but also generates a `hoogle` and `haddock` indexes | 
					
						
							|  |  |  |  | for all the packages, and provides a wrapper script around `hoogle` binary that | 
					
						
							|  |  |  |  | uses all those things. A precise name for this thing would be | 
					
						
							|  |  |  |  | "`ghcWithPackagesAndHoogleAndDocumentationIndexes`", which is, regrettably, too | 
					
						
							|  |  |  |  | long and scary. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | For example, installing the following environment | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```nix | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   packageOverrides = super: let self = super.pkgs; in | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     myHaskellEnv = self.haskellPackages.ghcWithHoogle | 
					
						
							|  |  |  |  |                      (haskellPackages: with haskellPackages; [ | 
					
						
							|  |  |  |  |                        # libraries | 
					
						
							|  |  |  |  |                        arrows async cgi criterion | 
					
						
							|  |  |  |  |                        # tools | 
					
						
							|  |  |  |  |                        cabal-install haskintex | 
					
						
							|  |  |  |  |                      ]); | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | allows one to browse module documentation index [not too dissimilar to | 
					
						
							|  |  |  |  | this](https://downloads.haskell.org/~ghc/latest/docs/html/libraries/index.html) | 
					
						
							|  |  |  |  | for all the specified packages and their dependencies by directing a browser of | 
					
						
							|  |  |  |  | choice to `~/.nix-profiles/share/doc/hoogle/index.html` (or | 
					
						
							|  |  |  |  | `/run/current-system/sw/share/doc/hoogle/index.html` in case you put it in | 
					
						
							|  |  |  |  | `environment.systemPackages` in NixOS). | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | After you've marveled enough at that try adding the following to your | 
					
						
							|  |  |  |  | `~/.ghc/ghci.conf` | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | :def hoogle \s -> return $ ":! hoogle search -cl --count=15 \"" ++ s ++ "\"" | 
					
						
							|  |  |  |  | :def doc \s -> return $ ":! hoogle search -cl --info \"" ++ s ++ "\"" | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | and test it by typing into `ghci`: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | :hoogle a -> a | 
					
						
							|  |  |  |  | :doc a -> a | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Be sure to note the links to `haddock` files in the output. With any modern and | 
					
						
							|  |  |  |  | properly configured terminal emulator you can just click those links to | 
					
						
							|  |  |  |  | navigate there. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Finally, you can run | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							| 
									
										
										
										
											2018-01-01 19:16:23 -05:00
										 |  |  |  | hoogle server -p 8080 --local | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | and navigate to http://localhost:8080/ for your own local | 
					
						
							| 
									
										
										
										
											2018-01-01 19:16:23 -05:00
										 |  |  |  | [Hoogle](https://www.haskell.org/hoogle/). | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 21:09:16 +01:00
										 |  |  |  | ### How to build a Haskell project using Stack
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-30 09:25:32 -07:00
										 |  |  |  | [Stack](http://haskellstack.org) is a popular build tool for Haskell projects. | 
					
						
							| 
									
										
										
										
											2016-01-17 21:09:16 +01:00
										 |  |  |  | It has first-class support for Nix. Stack can optionally use Nix to | 
					
						
							|  |  |  |  | automatically select the right version of GHC and other build tools to build, | 
					
						
							|  |  |  |  | test and execute apps in an existing project downloaded from somewhere on the | 
					
						
							|  |  |  |  | Internet. Pass the `--nix` flag to any `stack` command to do so, e.g. | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | git clone --recursive http://github.com/yesodweb/wai | 
					
						
							|  |  |  |  | cd wai | 
					
						
							|  |  |  |  | stack --nix build | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-01-17 21:09:16 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | If you want `stack` to use Nix by default, you can add a `nix` section to the | 
					
						
							|  |  |  |  | `stack.yaml` file, as explained in the [Stack documentation][stack-nix-doc]. For | 
					
						
							|  |  |  |  | example: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```yaml | 
					
						
							|  |  |  |  | nix: | 
					
						
							|  |  |  |  |   enable: true | 
					
						
							|  |  |  |  |   packages: [pkgconfig zeromq zlib] | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-01-17 21:09:16 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | The example configuration snippet above tells Stack to create an ad hoc | 
					
						
							|  |  |  |  | environment for `nix-shell` as in the below section, in which the `pkgconfig`, | 
					
						
							|  |  |  |  | `zeromq` and `zlib` packages from Nixpkgs are available. All `stack` commands | 
					
						
							|  |  |  |  | will implicitly be executed inside this ad hoc environment. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Some projects have more sophisticated needs. For examples, some ad hoc | 
					
						
							|  |  |  |  | environments might need to expose Nixpkgs packages compiled in a certain way, or | 
					
						
							|  |  |  |  | with extra environment variables. In these cases, you'll need a `shell` field | 
					
						
							|  |  |  |  | instead of `packages`: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```yaml | 
					
						
							|  |  |  |  | nix: | 
					
						
							|  |  |  |  |   enable: true | 
					
						
							|  |  |  |  |   shell-file: shell.nix | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-01-17 21:09:16 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | For more on how to write a `shell.nix` file see the below section. You'll need | 
					
						
							|  |  |  |  | to express a derivation. Note that Nixpkgs ships with a convenience wrapper | 
					
						
							| 
									
										
										
										
											2016-03-04 21:24:42 +01:00
										 |  |  |  | function around `mkDerivation` called `haskell.lib.buildStackProject` to help you | 
					
						
							| 
									
										
										
										
											2016-01-17 21:09:16 +01:00
										 |  |  |  | create this derivation in exactly the way Stack expects. All of the same inputs | 
					
						
							|  |  |  |  | as `mkDerivation` can be provided. For example, to build a Stack project that | 
					
						
							|  |  |  |  | including packages that link against a version of the R library compiled with | 
					
						
							|  |  |  |  | special options turned on: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```nix | 
					
						
							|  |  |  |  | with (import <nixpkgs> { }); | 
					
						
							| 
									
										
										
										
											2016-01-17 21:09:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | let R = pkgs.R.override { enableStrictBarrier = true; }; | 
					
						
							|  |  |  |  | in | 
					
						
							|  |  |  |  | haskell.lib.buildStackProject { | 
					
						
							|  |  |  |  |   name = "HaskellR"; | 
					
						
							|  |  |  |  |   buildInputs = [ R zeromq zlib ]; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-01-17 21:09:16 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-05 00:30:37 +02:00
										 |  |  |  | You can select a particular GHC version to compile with by setting the | 
					
						
							|  |  |  |  | `ghc` attribute as an argument to `buildStackProject`. Better yet, let | 
					
						
							|  |  |  |  | Stack choose what GHC version it wants based on the snapshot specified | 
					
						
							|  |  |  |  | in `stack.yaml` (only works with Stack >= 1.1.3): | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```nix | 
					
						
							|  |  |  |  | {nixpkgs ? import <nixpkgs> { }, ghc ? nixpkgs.ghc}: | 
					
						
							| 
									
										
										
										
											2016-06-05 00:30:37 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | with nixpkgs; | 
					
						
							| 
									
										
										
										
											2016-06-05 00:30:37 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | let R = pkgs.R.override { enableStrictBarrier = true; }; | 
					
						
							|  |  |  |  | in | 
					
						
							|  |  |  |  | haskell.lib.buildStackProject { | 
					
						
							|  |  |  |  |   name = "HaskellR"; | 
					
						
							|  |  |  |  |   buildInputs = [ R zeromq zlib ]; | 
					
						
							|  |  |  |  |   inherit ghc; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-06-05 00:30:37 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 21:09:16 +01:00
										 |  |  |  | [stack-nix-doc]: http://docs.haskellstack.org/en/stable/nix_integration.html | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ### How to create ad hoc environments for `nix-shell`
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | The easiest way to create an ad hoc development environment is to run | 
					
						
							|  |  |  |  | `nix-shell` with the appropriate GHC environment given on the command-line: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [mtl pandoc])" | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | For more sophisticated use-cases, however, it's more convenient to save the | 
					
						
							|  |  |  |  | desired configuration in a file called `shell.nix` that looks like this: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```nix | 
					
						
							|  |  |  |  | { nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }: | 
					
						
							|  |  |  |  | let | 
					
						
							|  |  |  |  |   inherit (nixpkgs) pkgs; | 
					
						
							|  |  |  |  |   ghc = pkgs.haskell.packages.${compiler}.ghcWithPackages (ps: with ps; [ | 
					
						
							|  |  |  |  |           monad-par mtl | 
					
						
							|  |  |  |  |         ]); | 
					
						
							|  |  |  |  | in | 
					
						
							|  |  |  |  | pkgs.stdenv.mkDerivation { | 
					
						
							|  |  |  |  |   name = "my-haskell-env-0"; | 
					
						
							|  |  |  |  |   buildInputs = [ ghc ]; | 
					
						
							|  |  |  |  |   shellHook = "eval $(egrep ^export ${ghc}/bin/ghc)"; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Now run `nix-shell` --- or even `nix-shell --pure` --- to enter a shell | 
					
						
							|  |  |  |  | environment that has the appropriate compiler in `$PATH`. If you use `--pure`, | 
					
						
							|  |  |  |  | then add all other packages that your development environment needs into the | 
					
						
							|  |  |  |  | `buildInputs` attribute. If you'd like to switch to a different compiler | 
					
						
							|  |  |  |  | version, then pass an appropriate `compiler` argument to the expression, i.e. | 
					
						
							|  |  |  |  | `nix-shell --argstr compiler ghc784`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | If you need such an environment because you'd like to compile a Hackage package | 
					
						
							|  |  |  |  | outside of Nix --- i.e. because you're hacking on the latest version from Git | 
					
						
							|  |  |  |  | ---, then the package set provides suitable nix-shell environments for you | 
					
						
							|  |  |  |  | already! Every Haskell package has an `env` attribute that provides a shell | 
					
						
							|  |  |  |  | environment suitable for compiling that particular package. If you'd like to | 
					
						
							|  |  |  |  | hack the `lens` library, for example, then you just have to check out the | 
					
						
							|  |  |  |  | source code and enter the appropriate environment: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | $ cabal get lens-4.11 && cd lens-4.11 | 
					
						
							|  |  |  |  | Downloading lens-4.11... | 
					
						
							|  |  |  |  | Unpacking to lens-4.11/ | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | $ nix-shell "<nixpkgs>" -A haskellPackages.lens.env | 
					
						
							|  |  |  |  | [nix-shell:/tmp/lens-4.11]$ | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | At point, you can run `cabal configure`, `cabal build`, and all the other | 
					
						
							|  |  |  |  | development commands. Note that you need `cabal-install` installed in your | 
					
						
							|  |  |  |  | `$PATH` already to use it here --- the `nix-shell` environment does not provide | 
					
						
							|  |  |  |  | it. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ## How to create Nix builds for your own private Haskell packages
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | If your own Haskell packages have build instructions for Cabal, then you can | 
					
						
							|  |  |  |  | convert those automatically into build instructions for Nix using the | 
					
						
							|  |  |  |  | `cabal2nix` utility, which you can install into your profile by running | 
					
						
							|  |  |  |  | `nix-env -i cabal2nix`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ### How to build a stand-alone project
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | For example, let's assume that you're working on a private project called | 
					
						
							|  |  |  |  | `foo`. To generate a Nix build expression for it, change into the project's | 
					
						
							|  |  |  |  | top-level directory and run the command: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | cabal2nix . > foo.nix | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | Then write the following snippet into a file called `default.nix`: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```nix | 
					
						
							|  |  |  |  | { nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }: | 
					
						
							|  |  |  |  | nixpkgs.pkgs.haskell.packages.${compiler}.callPackage ./foo.nix { } | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Finally, store the following code in a file called `shell.nix`: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```nix | 
					
						
							|  |  |  |  | { nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }: | 
					
						
							|  |  |  |  | (import ./default.nix { inherit nixpkgs compiler; }).env | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | At this point, you can run `nix-build` to have Nix compile your project and | 
					
						
							|  |  |  |  | install it into a Nix store path. The local directory will contain a symlink | 
					
						
							|  |  |  |  | called `result` after `nix-build` returns that points into that location. Of | 
					
						
							|  |  |  |  | course, passing the flag `--argstr compiler ghc763` allows switching the build | 
					
						
							|  |  |  |  | to any version of GHC currently supported. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Furthermore, you can call `nix-shell` to enter an interactive development | 
					
						
							|  |  |  |  | environment in which you can use `cabal configure` and `cabal build` to develop | 
					
						
							|  |  |  |  | your code. That environment will automatically contain a proper GHC derivation | 
					
						
							|  |  |  |  | with all the required libraries registered as well as all the system-level | 
					
						
							|  |  |  |  | libraries your package might need. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | If your package does not depend on any system-level libraries, then it's | 
					
						
							|  |  |  |  | sufficient to run | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-shell --command "cabal configure" | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | once to set up your build. `cabal-install` determines the absolute paths to all | 
					
						
							|  |  |  |  | resources required for the build and writes them into a config file in the | 
					
						
							|  |  |  |  | `dist/` directory. Once that's done, you can run `cabal build` and any other | 
					
						
							|  |  |  |  | command for that project even outside of the `nix-shell` environment. This | 
					
						
							|  |  |  |  | feature is particularly nice for those of us who like to edit their code with | 
					
						
							|  |  |  |  | an IDE, like Emacs' `haskell-mode`, because it's not necessary to start Emacs | 
					
						
							|  |  |  |  | inside of nix-shell just to make it find out the necessary settings for | 
					
						
							|  |  |  |  | building the project; `cabal-install` has already done that for us. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | If you want to do some quick-and-dirty hacking and don't want to bother setting | 
					
						
							|  |  |  |  | up a `default.nix` and `shell.nix` file manually, then you can use the | 
					
						
							|  |  |  |  | `--shell` flag offered by `cabal2nix` to have it generate a stand-alone | 
					
						
							|  |  |  |  | `nix-shell` environment for you. With that feature, running | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | cabal2nix --shell . > shell.nix | 
					
						
							|  |  |  |  | nix-shell --command "cabal configure" | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | is usually enough to set up a build environment for any given Haskell package. | 
					
						
							|  |  |  |  | You can even use that generated file to run `nix-build`, too: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-build shell.nix | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ### How to build projects that depend on each other
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | If you have multiple private Haskell packages that depend on each other, then | 
					
						
							|  |  |  |  | you'll have to register those packages in the Nixpkgs set to make them visible | 
					
						
							|  |  |  |  | for the dependency resolution performed by `callPackage`. First of all, change | 
					
						
							|  |  |  |  | into each of your projects top-level directories and generate a `default.nix` | 
					
						
							|  |  |  |  | file with `cabal2nix`: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | cd ~/src/foo && cabal2nix . > default.nix | 
					
						
							|  |  |  |  | cd ~/src/bar && cabal2nix . > default.nix | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2017-02-01 16:03:42 +01:00
										 |  |  |  | Then edit your `~/.config/nixpkgs/config.nix` file to register those builds in the | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | default Haskell package set: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```nix | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   packageOverrides = super: let self = super.pkgs; in | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     haskellPackages = super.haskellPackages.override { | 
					
						
							|  |  |  |  |       overrides = self: super: { | 
					
						
							|  |  |  |  |         foo = self.callPackage ../src/foo {}; | 
					
						
							|  |  |  |  |         bar = self.callPackage ../src/bar {}; | 
					
						
							|  |  |  |  |       }; | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | Once that's accomplished, `nix-env -f "<nixpkgs>" -qA haskellPackages` will | 
					
						
							|  |  |  |  | show your packages like any other package from Hackage, and you can build them | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-build "<nixpkgs>" -A haskellPackages.foo | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | or enter an interactive shell environment suitable for building them: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-shell "<nixpkgs>" -A haskellPackages.bar.env | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ## Miscellaneous Topics
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ### How to build with profiling enabled
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Every Haskell package set takes a function called `overrides` that you can use | 
					
						
							|  |  |  |  | to manipulate the package as much as you please. One useful application of this | 
					
						
							|  |  |  |  | feature is to replace the default `mkDerivation` function with one that enables | 
					
						
							| 
									
										
										
										
											2017-12-24 21:26:24 +00:00
										 |  |  |  | library profiling for all packages. To accomplish that add the following | 
					
						
							|  |  |  |  | snippet to your `~/.config/nixpkgs/config.nix` file: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```nix | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   packageOverrides = super: let self = super.pkgs; in | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     profiledHaskellPackages = self.haskellPackages.override { | 
					
						
							|  |  |  |  |       overrides = self: super: { | 
					
						
							|  |  |  |  |         mkDerivation = args: super.mkDerivation (args // { | 
					
						
							|  |  |  |  |           enableLibraryProfiling = true; | 
					
						
							|  |  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |     }; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | Then, replace instances of `haskellPackages` in the `cabal2nix`-generated | 
					
						
							|  |  |  |  | `default.nix` or `shell.nix` files with `profiledHaskellPackages`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ### How to override package versions in a compiler-specific package set
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Nixpkgs provides the latest version of | 
					
						
							|  |  |  |  | [`ghc-events`](http://hackage.haskell.org/package/ghc-events), which is 0.4.4.0 | 
					
						
							|  |  |  |  | at the time of this writing. This is fine for users of GHC 7.10.x, but GHC | 
					
						
							|  |  |  |  | 7.8.4 cannot compile that binary. Now, one way to solve that problem is to | 
					
						
							|  |  |  |  | register an older version of `ghc-events` in the 7.8.x-specific package set. | 
					
						
							|  |  |  |  | The first step is to generate Nix build instructions with `cabal2nix`: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | cabal2nix cabal://ghc-events-0.4.3.0 > ~/.nixpkgs/ghc-events-0.4.3.0.nix | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2017-02-01 16:03:42 +01:00
										 |  |  |  | Then add the override in `~/.config/nixpkgs/config.nix`: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```nix | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   packageOverrides = super: let self = super.pkgs; in | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     haskell = super.haskell // { | 
					
						
							|  |  |  |  |       packages = super.haskell.packages // { | 
					
						
							|  |  |  |  |         ghc784 = super.haskell.packages.ghc784.override { | 
					
						
							|  |  |  |  |           overrides = self: super: { | 
					
						
							|  |  |  |  |             ghc-events = self.callPackage ./ghc-events-0.4.3.0.nix {}; | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  |           }; | 
					
						
							|  |  |  |  |         }; | 
					
						
							|  |  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |     }; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | This code is a little crazy, no doubt, but it's necessary because the intuitive | 
					
						
							|  |  |  |  | version | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```nix | 
					
						
							|  |  |  |  | { # ... | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |   haskell.packages.ghc784 = super.haskell.packages.ghc784.override { | 
					
						
							|  |  |  |  |     overrides = self: super: { | 
					
						
							|  |  |  |  |       ghc-events = self.callPackage ./ghc-events-0.4.3.0.nix {}; | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |   }; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | doesn't do what we want it to: that code replaces the `haskell` package set in | 
					
						
							|  |  |  |  | Nixpkgs with one that contains only one entry,`packages`, which contains only | 
					
						
							|  |  |  |  | one entry `ghc784`. This override loses the `haskell.compiler` set, and it | 
					
						
							|  |  |  |  | loses the `haskell.packages.ghcXYZ` sets for all compilers but GHC 7.8.4. To | 
					
						
							|  |  |  |  | avoid that problem, we have to perform the convoluted little dance from above, | 
					
						
							|  |  |  |  | iterating over each step in hierarchy. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Once it's accomplished, however, we can install a variant of `ghc-events` | 
					
						
							|  |  |  |  | that's compiled with GHC 7.8.4: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-env -f "<nixpkgs>" -iA haskell.packages.ghc784.ghc-events | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | Unfortunately, it turns out that this build fails again while executing the | 
					
						
							|  |  |  |  | test suite! Apparently, the release archive on Hackage is missing some data | 
					
						
							|  |  |  |  | files that the test suite requires, so we cannot run it. We accomplish that by | 
					
						
							|  |  |  |  | re-generating the Nix expression with the `--no-check` flag: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | cabal2nix --no-check cabal://ghc-events-0.4.3.0 > ~/.nixpkgs/ghc-events-0.4.3.0.nix | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | Now the builds succeeds. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Of course, in the concrete example of `ghc-events` this whole exercise is not | 
					
						
							|  |  |  |  | an ideal solution, because `ghc-events` can analyze the output emitted by any | 
					
						
							|  |  |  |  | version of GHC later than 6.12 regardless of the compiler version that was used | 
					
						
							| 
									
										
										
										
											2016-11-08 17:42:27 +00:00
										 |  |  |  | to build the `ghc-events` executable, so strictly speaking there's no reason to | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | prefer one built with GHC 7.8.x in the first place. However, for users who | 
					
						
							|  |  |  |  | cannot use GHC 7.10.x at all for some reason, the approach of downgrading to an | 
					
						
							|  |  |  |  | older version might be useful. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-21 19:37:49 +02:00
										 |  |  |  | ### How to override packages in all compiler-specific package sets
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | In the previous section we learned how to override a package in a single | 
					
						
							|  |  |  |  | compiler-specific package set. You may have some overrides defined that you want | 
					
						
							|  |  |  |  | to use across multiple package sets. To accomplish this you could use the | 
					
						
							|  |  |  |  | technique that we learned in the previous section by repeating the overrides for | 
					
						
							|  |  |  |  | all the compiler-specific package sets. For example: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```nix | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   packageOverrides = super: let self = super.pkgs; in | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     haskell = super.haskell // { | 
					
						
							|  |  |  |  |       packages = super.haskell.packages // { | 
					
						
							|  |  |  |  |         ghc784 = super.haskell.packages.ghc784.override { | 
					
						
							|  |  |  |  |           overrides = self: super: { | 
					
						
							|  |  |  |  |             my-package = ...; | 
					
						
							|  |  |  |  |             my-other-package = ...; | 
					
						
							|  |  |  |  |           }; | 
					
						
							|  |  |  |  |         }; | 
					
						
							|  |  |  |  |         ghc822 = super.haskell.packages.ghc784.override { | 
					
						
							|  |  |  |  |           overrides = self: super: { | 
					
						
							|  |  |  |  |             my-package = ...; | 
					
						
							|  |  |  |  |             my-other-package = ...; | 
					
						
							|  |  |  |  |           }; | 
					
						
							|  |  |  |  |         }; | 
					
						
							|  |  |  |  |         ... | 
					
						
							|  |  |  |  |       }; | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | However there's a more convenient way to override all compiler-specific package | 
					
						
							|  |  |  |  | sets at once: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```nix | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   packageOverrides = super: let self = super.pkgs; in | 
					
						
							|  |  |  |  |   { | 
					
						
							|  |  |  |  |     haskell = super.haskell // { | 
					
						
							|  |  |  |  |       packageOverrides = self: super: { | 
					
						
							|  |  |  |  |         my-package = ...; | 
					
						
							|  |  |  |  |         my-other-package = ...; | 
					
						
							|  |  |  |  |       }; | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ### How to recover from GHC's infamous non-deterministic library ID bug
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | GHC and distributed build farms don't get along well: | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |   - https://ghc.haskell.org/trac/ghc/ticket/4012 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | When you see an error like this one | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | package foo-0.7.1.0 is broken due to missing package | 
					
						
							|  |  |  |  | text-1.2.0.4-98506efb1b9ada233bb5c2b2db516d91 | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | then you have to download and re-install `foo` and all its dependents from | 
					
						
							|  |  |  |  | scratch: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-store -q --referrers /nix/store/*-haskell-text-1.2.0.4 \ | 
					
						
							|  |  |  |  |   | xargs -L 1 nix-store --repair-path | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | If you're using additional Hydra servers other than `hydra.nixos.org`, then it | 
					
						
							|  |  |  |  | might be necessary to purge the local caches that store data from those | 
					
						
							|  |  |  |  | machines to disable these binary channels for the duration of the previous | 
					
						
							|  |  |  |  | command, i.e. by running: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							| 
									
										
										
										
											2018-03-20 18:26:13 +01:00
										 |  |  |  | rm ~/.cache/nix/binary-cache*.sqlite | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ### Builds on Darwin fail with `math.h` not found
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | Users of GHC on Darwin have occasionally reported that builds fail, because the | 
					
						
							|  |  |  |  | compiler complains about a missing include file: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | fatal error: 'math.h' file not found | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | The issue has been discussed at length in [ticket | 
					
						
							|  |  |  |  | 6390](https://github.com/NixOS/nixpkgs/issues/6390), and so far no good | 
					
						
							|  |  |  |  | solution has been proposed. As a work-around, users who run into this problem | 
					
						
							|  |  |  |  | can configure the environment variables | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | export NIX_CFLAGS_COMPILE="-idirafter /usr/include" | 
					
						
							|  |  |  |  | export NIX_CFLAGS_LINK="-L/usr/lib" | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | in their `~/.bashrc` file to avoid the compiler error. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 21:19:14 +01:00
										 |  |  |  | ### Builds using Stack complain about missing system libraries
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | --  While building package zlib-0.5.4.2 using: | 
					
						
							|  |  |  |  |   runhaskell -package=Cabal-1.22.4.0 -clear-package-db [... lots of flags ...] | 
					
						
							|  |  |  |  | Process exited with code: ExitFailure 1 | 
					
						
							|  |  |  |  | Logs have been written to: /home/foo/src/stack-ide/.stack-work/logs/zlib-0.5.4.2.log | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Configuring zlib-0.5.4.2... | 
					
						
							|  |  |  |  | Setup.hs: Missing dependency on a foreign library: | 
					
						
							|  |  |  |  | * Missing (or bad) header file: zlib.h | 
					
						
							|  |  |  |  | This problem can usually be solved by installing the system package that | 
					
						
							|  |  |  |  | provides this library (you may need the "-dev" version). If the library is | 
					
						
							|  |  |  |  | already installed but in a non-standard location then you can use the flags | 
					
						
							|  |  |  |  | --extra-include-dirs= and --extra-lib-dirs= to specify where it is. | 
					
						
							|  |  |  |  | If the header file does exist, it may contain errors that are caught by the C | 
					
						
							|  |  |  |  | compiler at the preprocessing stage. In this case you can re-run configure | 
					
						
							|  |  |  |  | with the verbosity flag -v3 to see the error messages. | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | When you run the build inside of the nix-shell environment, the system | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | is configured to find `libz.so` without any special flags -- the compiler | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | and linker "just know" how to find it. Consequently, Cabal won't record | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | any search paths for `libz.so` in the package description, which means | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | that the package works fine inside of nix-shell, but once you leave the | 
					
						
							|  |  |  |  | shell the shared object can no longer be found. That issue is by no | 
					
						
							|  |  |  |  | means specific to Stack: you'll have that problem with any other | 
					
						
							|  |  |  |  | Haskell package that's built inside of nix-shell but run outside of that | 
					
						
							|  |  |  |  | environment. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 21:19:14 +01:00
										 |  |  |  | You can remedy this issue in several ways. The easiest is to add a `nix` section | 
					
						
							|  |  |  |  | to the `stack.yaml` like the following: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```yaml | 
					
						
							|  |  |  |  | nix: | 
					
						
							|  |  |  |  |   enable: true | 
					
						
							|  |  |  |  |   packages: [ zlib ] | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Stack's Nix support knows to add `${zlib.out}/lib` and `${zlib.dev}/include` | 
					
						
							|  |  |  |  | as an `--extra-lib-dirs` and `extra-include-dirs`, respectively. | 
					
						
							|  |  |  |  | Alternatively, you can achieve the same effect by hand. First of all, run | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | $ nix-build --no-out-link "<nixpkgs>" -A zlib | 
					
						
							|  |  |  |  | /nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8 | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | to find out the store path of the system's zlib library. Now, you can | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |   1. add that path (plus a "/lib" suffix) to your `$LD_LIBRARY_PATH` | 
					
						
							|  |  |  |  |     environment variable to make sure your system linker finds `libz.so` | 
					
						
							|  |  |  |  |     automatically. It's no pretty solution, but it will work. | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |   2. As a variant of (1), you can also install any number of system | 
					
						
							|  |  |  |  |     libraries into your user's profile (or some other profile) and point | 
					
						
							|  |  |  |  |     `$LD_LIBRARY_PATH` to that profile instead, so that you don't have to | 
					
						
							|  |  |  |  |     list dozens of those store paths all over the place. | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |   3. The solution I prefer is to call stack with an appropriate | 
					
						
							|  |  |  |  |     --extra-lib-dirs flag like so: | 
					
						
							|  |  |  |  |     ```shell | 
					
						
							|  |  |  |  |     stack --extra-lib-dirs=/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8/lib build | 
					
						
							|  |  |  |  |     ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-14 11:18:29 +08:00
										 |  |  |  | Typically, you'll need `--extra-include-dirs` as well. It's possible | 
					
						
							|  |  |  |  | to add those flag to the project's `stack.yaml` or your user's | 
					
						
							|  |  |  |  | global `~/.stack/global/stack.yaml` file so that you don't have to | 
					
						
							|  |  |  |  | specify them manually every time. But again, you're likely better off | 
					
						
							|  |  |  |  | using Stack's Nix support instead. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The same thing applies to `cabal configure`, of course, if you're | 
					
						
							|  |  |  |  | building with `cabal-install` instead of Stack. | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ### Creating statically linked binaries
 | 
					
						
							| 
									
										
										
										
											2015-11-14 12:32:51 -08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | There are two levels of static linking. The first option is to configure the | 
					
						
							|  |  |  |  | build with the Cabal flag `--disable-executable-dynamic`. In Nix expressions, | 
					
						
							|  |  |  |  | this can be achieved by setting the attribute: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | enableSharedExecutables = false; | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-11-14 12:32:51 -08:00
										 |  |  |  | That gives you a binary with statically linked Haskell libraries and | 
					
						
							|  |  |  |  | dynamically linked system libraries. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | To link both Haskell libraries and system libraries statically, the additional | 
					
						
							|  |  |  |  | flags `--ghc-option=-optl=-static --ghc-option=-optl=-pthread` need to be used. | 
					
						
							|  |  |  |  | In Nix, this is accomplished with: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | configureFlags = [ "--ghc-option=-optl=-static" "--ghc-option=-optl=-pthread" ]; | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-11-14 12:32:51 -08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | It's important to realize, however, that most system libraries in Nix are | 
					
						
							|  |  |  |  | built as shared libraries only, i.e. there is just no static library | 
					
						
							|  |  |  |  | available that Cabal could link! | 
					
						
							| 
									
										
										
										
											2015-11-14 12:32:51 -08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-25 00:00:54 +01:00
										 |  |  |  | ### Building GHC with integer-simple
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | By default GHC implements the Integer type using the | 
					
						
							|  |  |  |  | [GNU Multiple Precision Arithmetic (GMP) library](https://gmplib.org/). | 
					
						
							|  |  |  |  | The implementation can be found in the | 
					
						
							|  |  |  |  | [integer-gmp](http://hackage.haskell.org/package/integer-gmp) package. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | A potential problem with this is that GMP is licensed under the | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | [GNU Lesser General Public License (LGPL)](http://www.gnu.org/copyleft/lesser.html), | 
					
						
							| 
									
										
										
										
											2017-01-25 00:00:54 +01:00
										 |  |  |  | a kind of "copyleft" license. According to the terms of the LGPL, paragraph 5, | 
					
						
							|  |  |  |  | you may distribute a program that is designed to be compiled and dynamically | 
					
						
							|  |  |  |  | linked with the library under the terms of your choice (i.e., commercially) but | 
					
						
							|  |  |  |  | if your program incorporates portions of the library, if it is linked | 
					
						
							|  |  |  |  | statically, then your program is a "derivative"--a "work based on the | 
					
						
							|  |  |  |  | library"--and according to paragraph 2, section c, you "must cause the whole of | 
					
						
							|  |  |  |  | the work to be licensed" under the terms of the LGPL (including for free). | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The LGPL licensing for GMP is a problem for the overall licensing of binary | 
					
						
							|  |  |  |  | programs compiled with GHC because most distributions (and builds) of GHC use | 
					
						
							| 
									
										
										
										
											2017-08-07 00:05:18 +02:00
										 |  |  |  | static libraries. (Dynamic libraries are currently distributed only for macOS.) | 
					
						
							| 
									
										
										
										
											2017-01-25 00:00:54 +01:00
										 |  |  |  | The LGPL licensing situation may be worse: even though | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | [The Glasgow Haskell Compiler License](https://www.haskell.org/ghc/license) | 
					
						
							| 
									
										
										
										
											2017-01-25 00:00:54 +01:00
										 |  |  |  | is essentially a "free software" license (BSD3), according to | 
					
						
							|  |  |  |  | paragraph 2 of the LGPL, GHC must be distributed under the terms of the LGPL! | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | To work around these problems GHC can be build with a slower but LGPL-free | 
					
						
							|  |  |  |  | alternative implemention for Integer called | 
					
						
							|  |  |  |  | [integer-simple](http://hackage.haskell.org/package/integer-simple). | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | To get a GHC compiler build with `integer-simple` instead of `integer-gmp` use | 
					
						
							| 
									
										
										
										
											2017-03-12 23:35:28 +01:00
										 |  |  |  | the attribute: `haskell.compiler.integer-simple."${ghcVersion}"`. | 
					
						
							| 
									
										
										
										
											2017-01-25 00:00:54 +01:00
										 |  |  |  | For example: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | $ nix-build -E '(import <nixpkgs> {}).haskell.compiler.integer-simple.ghc802' | 
					
						
							|  |  |  |  | ... | 
					
						
							|  |  |  |  | $ result/bin/ghc-pkg list | grep integer | 
					
						
							|  |  |  |  |     integer-simple-0.1.1.1 | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2017-01-25 00:00:54 +01:00
										 |  |  |  | The following command displays the complete list of GHC compilers build with `integer-simple`: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | $ nix-env -f "<nixpkgs>" -qaP -A haskell.compiler.integer-simple | 
					
						
							|  |  |  |  | haskell.compiler.integer-simple.ghc7102  ghc-7.10.2 | 
					
						
							|  |  |  |  | haskell.compiler.integer-simple.ghc7103  ghc-7.10.3 | 
					
						
							|  |  |  |  | haskell.compiler.integer-simple.ghc722   ghc-7.2.2 | 
					
						
							|  |  |  |  | haskell.compiler.integer-simple.ghc742   ghc-7.4.2 | 
					
						
							|  |  |  |  | haskell.compiler.integer-simple.ghc783   ghc-7.8.3 | 
					
						
							|  |  |  |  | haskell.compiler.integer-simple.ghc784   ghc-7.8.4 | 
					
						
							|  |  |  |  | haskell.compiler.integer-simple.ghc801   ghc-8.0.1 | 
					
						
							|  |  |  |  | haskell.compiler.integer-simple.ghc802   ghc-8.0.2 | 
					
						
							|  |  |  |  | haskell.compiler.integer-simple.ghcHEAD  ghc-8.1.20170106 | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2017-01-25 00:00:54 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | To get a package set supporting `integer-simple` use the attribute: | 
					
						
							| 
									
										
										
										
											2017-03-12 23:35:28 +01:00
										 |  |  |  | `haskell.packages.integer-simple."${ghcVersion}"`. For example | 
					
						
							| 
									
										
										
										
											2017-01-25 00:00:54 +01:00
										 |  |  |  | use the following to get the `scientific` package build with `integer-simple`: | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  | ```shell | 
					
						
							|  |  |  |  | nix-build -A haskell.packages.integer-simple.ghc802.scientific | 
					
						
							|  |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-30 14:40:54 +02:00
										 |  |  |  | ### Quality assurance
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The `haskell.lib` library includes a number of functions for checking for | 
					
						
							|  |  |  |  | various imperfections in Haskell packages. It's useful to apply these functions | 
					
						
							|  |  |  |  | to your own Haskell packages and integrate that in a Continuous Integration | 
					
						
							|  |  |  |  | server like [hydra](https://nixos.org/hydra/) to assure your packages maintain a | 
					
						
							|  |  |  |  | minimum level of quality. This section discusses some of these functions. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-10 13:09:52 +02:00
										 |  |  |  | #### failOnAllWarnings
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Applying `haskell.lib.failOnAllWarnings` to a Haskell package enables the | 
					
						
							|  |  |  |  | `-Wall` and `-Werror` GHC options to turn all warnings into build failures. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-30 14:40:54 +02:00
										 |  |  |  | #### buildStrictly
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-10 13:09:52 +02:00
										 |  |  |  | Applying `haskell.lib.buildStrictly` to a Haskell package calls | 
					
						
							|  |  |  |  | `failOnAllWarnings` on the given package to turn all warnings into build | 
					
						
							|  |  |  |  | failures. Additionally the source of your package is gotten from first invoking | 
					
						
							|  |  |  |  | `cabal sdist` to ensure all needed files are listed in the Cabal file. | 
					
						
							| 
									
										
										
										
											2017-08-30 14:40:54 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | #### checkUnusedPackages
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | Applying `haskell.lib.checkUnusedPackages` to a Haskell package invokes | 
					
						
							|  |  |  |  | the [packunused](http://hackage.haskell.org/package/packunused) tool on the | 
					
						
							|  |  |  |  | package. `packunused` complains when it finds packages listed as build-depends | 
					
						
							|  |  |  |  | in the Cabal file which are redundant. For example: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | $ nix-build -E 'let pkgs = import <nixpkgs> {}; in pkgs.haskell.lib.checkUnusedPackages {} pkgs.haskellPackages.scientific' | 
					
						
							|  |  |  |  | these derivations will be built: | 
					
						
							|  |  |  |  |   /nix/store/3lc51cxj2j57y3zfpq5i69qbzjpvyci1-scientific-0.3.5.1.drv | 
					
						
							|  |  |  |  | ... | 
					
						
							|  |  |  |  | detected package components | 
					
						
							|  |  |  |  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |  - library | 
					
						
							|  |  |  |  |  - testsuite(s): test-scientific | 
					
						
							|  |  |  |  |  - benchmark(s): bench-scientific* | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | (component names suffixed with '*' are not configured to be built) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | library | 
					
						
							|  |  |  |  | ~~~~~~~ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | The following package dependencies seem redundant: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |  - ghc-prim-0.5.0.0 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | testsuite(test-scientific) | 
					
						
							|  |  |  |  | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | no redundant packages dependencies found | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | builder for ‘/nix/store/3lc51cxj2j57y3zfpq5i69qbzjpvyci1-scientific-0.3.5.1.drv’ failed with exit code 1 | 
					
						
							|  |  |  |  | error: build of ‘/nix/store/3lc51cxj2j57y3zfpq5i69qbzjpvyci1-scientific-0.3.5.1.drv’ failed | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | As you can see, `packunused` finds out that although the testsuite component has | 
					
						
							|  |  |  |  | no redundant dependencies the library component of `scientific-0.3.5.1` depends | 
					
						
							|  |  |  |  | on `ghc-prim` which is unused in the library. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 10:50:37 +01:00
										 |  |  |  | ## Other resources
 | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |   - The Youtube video [Nix Loves Haskell](https://www.youtube.com/watch?v=BsBhi_r-OeE) | 
					
						
							|  |  |  |  |     provides an introduction into Haskell NG aimed at beginners. The slides are | 
					
						
							|  |  |  |  |     available at http://cryp.to/nixos-meetup-3-slides.pdf and also -- in a form | 
					
						
							|  |  |  |  |     ready for cut & paste -- at | 
					
						
							|  |  |  |  |     https://github.com/NixOS/cabal2nix/blob/master/doc/nixos-meetup-3-slides.md. | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |   - Another Youtube video is [Escaping Cabal Hell with Nix](https://www.youtube.com/watch?v=mQd3s57n_2Y), | 
					
						
							|  |  |  |  |     which discusses the subject of Haskell development with Nix but also provides | 
					
						
							|  |  |  |  |     a basic introduction to Nix as well, i.e. it's suitable for viewers with | 
					
						
							|  |  |  |  |     almost no prior Nix experience. | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |   - Oliver Charles wrote a very nice [Tutorial how to develop Haskell packages with Nix](http://wiki.ocharles.org.uk/Nix). | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |   - The *Journey into the Haskell NG infrastructure* series of postings | 
					
						
							|  |  |  |  |     describe the new Haskell infrastructure in great detail: | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-18 07:54:36 -04:00
										 |  |  |  |       - [Part 1](https://nixos.org/nix-dev/2015-January/015591.html) | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |         explains the differences between the old and the new code and gives | 
					
						
							|  |  |  |  |         instructions how to migrate to the new setup. | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-18 07:54:36 -04:00
										 |  |  |  |       - [Part 2](https://nixos.org/nix-dev/2015-January/015608.html) | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |         looks in-depth at how to tweak and configure your setup by means of | 
					
						
							|  |  |  |  |         overrides. | 
					
						
							| 
									
										
										
										
											2015-09-30 17:21:08 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-18 07:54:36 -04:00
										 |  |  |  |       - [Part 3](https://nixos.org/nix-dev/2015-April/016912.html) | 
					
						
							| 
									
										
										
										
											2017-03-07 14:16:01 +01:00
										 |  |  |  |         describes the infrastructure that keeps the Haskell package set in Nixpkgs | 
					
						
							|  |  |  |  |         up-to-date. |