forked from mirrors/nixpkgs
Merge pull request #23627 from alexeymuranov/haskell-doc-markdown
doc: enable code syntax highlighting
This commit is contained in:
commit
84b1643af5
|
@ -11,32 +11,35 @@ date: 2015-06-01
|
||||||
Nixpkgs distributes build instructions for all Haskell packages registered on
|
Nixpkgs distributes build instructions for all Haskell packages registered on
|
||||||
[Hackage](http://hackage.haskell.org/), but strangely enough normal Nix package
|
[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:
|
lookups don't seem to discover any of them, except for the default version of ghc, cabal-install, and stack:
|
||||||
|
```
|
||||||
$ nix-env -i alex
|
$ nix-env -i alex
|
||||||
error: selector ‘alex’ matches no derivations
|
error: selector ‘alex’ matches no derivations
|
||||||
$ nix-env -qa ghc
|
$ nix-env -qa ghc
|
||||||
ghc-7.10.2
|
ghc-7.10.2
|
||||||
|
```
|
||||||
|
|
||||||
The Haskell package set is not registered in the top-level namespace because it
|
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
|
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
|
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
|
avoided that by keeping all Haskell-related packages in a separate attribute
|
||||||
set called `haskellPackages`, which the following command will list:
|
set called `haskellPackages`, which the following command will list:
|
||||||
|
```
|
||||||
$ nix-env -f "<nixpkgs>" -qaP -A haskellPackages
|
$ nix-env -f "<nixpkgs>" -qaP -A haskellPackages
|
||||||
haskellPackages.a50 a50-0.5
|
haskellPackages.a50 a50-0.5
|
||||||
haskellPackages.abacate haskell-abacate-0.0.0.0
|
haskellPackages.abacate haskell-abacate-0.0.0.0
|
||||||
haskellPackages.abcBridge haskell-abcBridge-0.12
|
haskellPackages.abcBridge haskell-abcBridge-0.12
|
||||||
haskellPackages.afv afv-0.1.1
|
haskellPackages.afv afv-0.1.1
|
||||||
haskellPackages.alex alex-3.1.4
|
haskellPackages.alex alex-3.1.4
|
||||||
haskellPackages.Allure Allure-0.4.101.1
|
haskellPackages.Allure Allure-0.4.101.1
|
||||||
haskellPackages.alms alms-0.6.7
|
haskellPackages.alms alms-0.6.7
|
||||||
[... some 8000 entries omitted ...]
|
[... some 8000 entries omitted ...]
|
||||||
|
```
|
||||||
|
|
||||||
To install any of those packages into your profile, refer to them by their
|
To install any of those packages into your profile, refer to them by their
|
||||||
attribute path (first column):
|
attribute path (first column):
|
||||||
|
```shell
|
||||||
$ nix-env -f "<nixpkgs>" -iA haskellPackages.Allure ...
|
nix-env -f "<nixpkgs>" -iA haskellPackages.Allure ...
|
||||||
|
```
|
||||||
|
|
||||||
The attribute path of any Haskell packages corresponds to the name of that
|
The attribute path of any Haskell packages corresponds to the name of that
|
||||||
particular package on Hackage: the package `cabal-install` has the attribute
|
particular package on Hackage: the package `cabal-install` has the attribute
|
||||||
|
@ -58,55 +61,60 @@ 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
|
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`
|
`nix-env` an explicit `-f "<nixpkgs>"` parameter, but if you call `nix-env`
|
||||||
without that flag, then chances are the invocation fails:
|
without that flag, then chances are the invocation fails:
|
||||||
|
```
|
||||||
$ nix-env -iA haskellPackages.cabal-install
|
$ nix-env -iA haskellPackages.cabal-install
|
||||||
error: attribute ‘haskellPackages’ in selection path
|
error: attribute ‘haskellPackages’ in selection path
|
||||||
‘haskellPackages.cabal-install’ not found
|
‘haskellPackages.cabal-install’ not found
|
||||||
|
```
|
||||||
|
|
||||||
On NixOS, for example, Nixpkgs does *not* exist in the top-level namespace by
|
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
|
default. To figure out the proper attribute path, it's easiest to query for the
|
||||||
path of a well-known Nixpkgs package, i.e.:
|
path of a well-known Nixpkgs package, i.e.:
|
||||||
|
```
|
||||||
$ nix-env -qaP coreutils
|
$ nix-env -qaP coreutils
|
||||||
nixos.coreutils coreutils-8.23
|
nixos.coreutils coreutils-8.23
|
||||||
|
```
|
||||||
|
|
||||||
If your system responds like that (most NixOS installations will), then the
|
If your system responds like that (most NixOS installations will), then the
|
||||||
attribute path to `haskellPackages` is `nixos.haskellPackages`. Thus, if you
|
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
|
want to use `nix-env` without giving an explicit `-f` flag, then that's the way
|
||||||
to do it:
|
to do it:
|
||||||
|
```shell
|
||||||
$ nix-env -qaP -A nixos.haskellPackages
|
nix-env -qaP -A nixos.haskellPackages
|
||||||
$ nix-env -iA nixos.haskellPackages.cabal-install
|
nix-env -iA nixos.haskellPackages.cabal-install
|
||||||
|
```
|
||||||
|
|
||||||
Our current default compiler is GHC 7.10.x and the `haskellPackages` set
|
Our current default compiler is GHC 7.10.x and the `haskellPackages` set
|
||||||
contains packages built with that particular version. Nixpkgs contains the
|
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
|
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
|
family of package sets available that defines Hackage packages built with each
|
||||||
of those compilers, too:
|
of those compilers, too:
|
||||||
|
```shell
|
||||||
$ nix-env -f "<nixpkgs>" -qaP -A haskell.packages.ghc6123
|
nix-env -f "<nixpkgs>" -qaP -A haskell.packages.ghc6123
|
||||||
$ nix-env -f "<nixpkgs>" -qaP -A haskell.packages.ghc763
|
nix-env -f "<nixpkgs>" -qaP -A haskell.packages.ghc763
|
||||||
|
```
|
||||||
|
|
||||||
The name `haskellPackages` is really just a synonym for
|
The name `haskellPackages` is really just a synonym for
|
||||||
`haskell.packages.ghc7102`, because we prefer that package set internally and
|
`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
|
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
|
to compile your Haskell packages with any GHC version you please. The following
|
||||||
command displays the complete list of available compilers:
|
command displays the complete list of available compilers:
|
||||||
|
```
|
||||||
$ nix-env -f "<nixpkgs>" -qaP -A haskell.compiler
|
$ nix-env -f "<nixpkgs>" -qaP -A haskell.compiler
|
||||||
haskell.compiler.ghc6104 ghc-6.10.4
|
haskell.compiler.ghc6104 ghc-6.10.4
|
||||||
haskell.compiler.ghc6123 ghc-6.12.3
|
haskell.compiler.ghc6123 ghc-6.12.3
|
||||||
haskell.compiler.ghc704 ghc-7.0.4
|
haskell.compiler.ghc704 ghc-7.0.4
|
||||||
haskell.compiler.ghc722 ghc-7.2.2
|
haskell.compiler.ghc722 ghc-7.2.2
|
||||||
haskell.compiler.ghc742 ghc-7.4.2
|
haskell.compiler.ghc742 ghc-7.4.2
|
||||||
haskell.compiler.ghc763 ghc-7.6.3
|
haskell.compiler.ghc763 ghc-7.6.3
|
||||||
haskell.compiler.ghc784 ghc-7.8.4
|
haskell.compiler.ghc784 ghc-7.8.4
|
||||||
haskell.compiler.ghc7102 ghc-7.10.2
|
haskell.compiler.ghc7102 ghc-7.10.2
|
||||||
haskell.compiler.ghcHEAD ghc-7.11.20150402
|
haskell.compiler.ghcHEAD ghc-7.11.20150402
|
||||||
haskell.compiler.ghcNokinds ghc-nokinds-7.11.20150704
|
haskell.compiler.ghcNokinds ghc-nokinds-7.11.20150704
|
||||||
haskell.compiler.ghcjs ghcjs-0.1.0
|
haskell.compiler.ghcjs ghcjs-0.1.0
|
||||||
haskell.compiler.jhc jhc-0.8.2
|
haskell.compiler.jhc jhc-0.8.2
|
||||||
haskell.compiler.uhc uhc-1.1.9.0
|
haskell.compiler.uhc uhc-1.1.9.0
|
||||||
|
```
|
||||||
|
|
||||||
We have no package sets for `jhc` or `uhc` yet, unfortunately, but for every
|
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.
|
version of GHC listed above, there exists a package set based on that compiler.
|
||||||
|
@ -121,8 +129,9 @@ A simple development environment consists of a Haskell compiler and one or both
|
||||||
of the tools `cabal-install` and `stack`. We saw in section
|
of the tools `cabal-install` and `stack`. We saw in section
|
||||||
[How to install Haskell packages] how you can install those programs into your
|
[How to install Haskell packages] how you can install those programs into your
|
||||||
user profile:
|
user profile:
|
||||||
|
```shell
|
||||||
$ nix-env -f "<nixpkgs>" -iA haskellPackages.ghc haskellPackages.cabal-install
|
nix-env -f "<nixpkgs>" -iA haskellPackages.ghc haskellPackages.cabal-install
|
||||||
|
```
|
||||||
|
|
||||||
Instead of the default package set `haskellPackages`, you can also use the more
|
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
|
precise name `haskell.compiler.ghc7102`, which has the advantage that it refers
|
||||||
|
@ -131,24 +140,25 @@ given time.
|
||||||
|
|
||||||
Once you've made those tools available in `$PATH`, it's possible to build
|
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:
|
Hackage packages the same way people without access to Nix do it all the time:
|
||||||
|
```shell
|
||||||
$ cabal get lens-4.11 && cd lens-4.11
|
cabal get lens-4.11 && cd lens-4.11
|
||||||
$ cabal install -j --dependencies-only
|
cabal install -j --dependencies-only
|
||||||
$ cabal configure
|
cabal configure
|
||||||
$ cabal build
|
cabal build
|
||||||
|
```
|
||||||
|
|
||||||
If you enjoy working with Cabal sandboxes, then that's entirely possible too:
|
If you enjoy working with Cabal sandboxes, then that's entirely possible too:
|
||||||
just execute the command
|
just execute the command
|
||||||
|
```shell
|
||||||
$ cabal sandbox init
|
cabal sandbox init
|
||||||
|
```
|
||||||
before installing the required dependencies.
|
before installing the required dependencies.
|
||||||
|
|
||||||
The `nix-shell` utility makes it easy to switch to a different compiler
|
The `nix-shell` utility makes it easy to switch to a different compiler
|
||||||
version; just enter the Nix shell environment with the command
|
version; just enter the Nix shell environment with the command
|
||||||
|
```shell
|
||||||
$ nix-shell -p haskell.compiler.ghc784
|
nix-shell -p haskell.compiler.ghc784
|
||||||
|
```
|
||||||
to bring GHC 7.8.4 into `$PATH`. Alternatively, you can use Stack instead of
|
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
|
`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.
|
per-project. It uses `nix-shell` under the hood when Nix support is turned on.
|
||||||
|
@ -159,8 +169,9 @@ 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,
|
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
|
then it's even sufficient to just run the `cabal configure` command inside of
|
||||||
the shell:
|
the shell:
|
||||||
|
```shell
|
||||||
$ nix-shell -p haskell.compiler.ghc784 --command "cabal configure"
|
nix-shell -p haskell.compiler.ghc784 --command "cabal configure"
|
||||||
|
```
|
||||||
|
|
||||||
Afterwards, all other commands like `cabal build` work just fine in any shell
|
Afterwards, all other commands like `cabal build` work just fine in any shell
|
||||||
environment, because the configure phase recorded the absolute paths to all
|
environment, because the configure phase recorded the absolute paths to all
|
||||||
|
@ -187,17 +198,18 @@ packages, which determines the libraries known to that particular version of
|
||||||
GHC. For example, the Nix expression `ghcWithPackages (pkgs: [pkgs.mtl])`
|
GHC. For example, the Nix expression `ghcWithPackages (pkgs: [pkgs.mtl])`
|
||||||
generates a copy of GHC that has the `mtl` library registered in addition to
|
generates a copy of GHC that has the `mtl` library registered in addition to
|
||||||
its normal core packages:
|
its normal core packages:
|
||||||
|
```
|
||||||
|
$ nix-shell -p "haskellPackages.ghcWithPackages (pkgs: [pkgs.mtl])"
|
||||||
|
|
||||||
$ nix-shell -p "haskellPackages.ghcWithPackages (pkgs: [pkgs.mtl])"
|
[nix-shell:~]$ ghc-pkg list mtl
|
||||||
|
/nix/store/zy79...-ghc-7.10.2/lib/ghc-7.10.2/package.conf.d:
|
||||||
[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
|
mtl-2.2.1
|
||||||
|
```
|
||||||
|
|
||||||
This function allows users to define their own development environment by means
|
This function allows users to define their own development environment by means
|
||||||
of an override. After adding the following snippet to `~/.config/nixpkgs/config.nix`,
|
of an override. After adding the following snippet to `~/.config/nixpkgs/config.nix`,
|
||||||
|
```nix
|
||||||
{
|
{
|
||||||
packageOverrides = super: let self = super.pkgs; in
|
packageOverrides = super: let self = super.pkgs; in
|
||||||
{
|
{
|
||||||
myHaskellEnv = self.haskell.packages.ghc7102.ghcWithPackages
|
myHaskellEnv = self.haskell.packages.ghc7102.ghcWithPackages
|
||||||
|
@ -208,8 +220,8 @@ of an override. After adding the following snippet to `~/.config/nixpkgs/config.
|
||||||
cabal-install haskintex
|
cabal-install haskintex
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
```
|
||||||
it's possible to install that compiler with `nix-env -f "<nixpkgs>" -iA
|
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
|
myHaskellEnv`. If you'd like to switch that development environment to a
|
||||||
different version of GHC, just replace the `ghc7102` bit in the previous
|
different version of GHC, just replace the `ghc7102` bit in the previous
|
||||||
|
@ -221,14 +233,15 @@ file conflicts.)
|
||||||
The generated `ghc` program is a wrapper script that re-directs the real
|
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
|
GHC executable to use a new `lib` directory --- one that we specifically
|
||||||
constructed to contain all those packages the user requested:
|
constructed to contain all those packages the user requested:
|
||||||
|
```
|
||||||
$ cat $(type -p ghc)
|
$ cat $(type -p ghc)
|
||||||
#! /nix/store/xlxj...-bash-4.3-p33/bin/bash -e
|
#! /nix/store/xlxj...-bash-4.3-p33/bin/bash -e
|
||||||
export NIX_GHC=/nix/store/19sm...-ghc-7.10.2/bin/ghc
|
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_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_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
|
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" "$@"
|
exec /nix/store/j50p...-ghc-7.10.2/bin/ghc "-B$NIX_GHC_LIBDIR" "$@"
|
||||||
|
```
|
||||||
|
|
||||||
The variables `$NIX_GHC`, `$NIX_GHCPKG`, etc. point to the *new* store path
|
The variables `$NIX_GHC`, `$NIX_GHCPKG`, etc. point to the *new* store path
|
||||||
`ghcWithPackages` constructed specifically for this environment. The last line
|
`ghcWithPackages` constructed specifically for this environment. The last line
|
||||||
|
@ -248,23 +261,25 @@ than trying to guess them at compile-time.
|
||||||
To make sure that mechanism works properly all the time, we recommend that you
|
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.
|
set those variables to meaningful values in your shell environment, too, i.e.
|
||||||
by adding the following code to your `~/.bashrc`:
|
by adding the following code to your `~/.bashrc`:
|
||||||
|
```bash
|
||||||
if type >/dev/null 2>&1 -p ghc; then
|
if type >/dev/null 2>&1 -p ghc; then
|
||||||
eval "$(egrep ^export "$(type -p ghc)")"
|
eval "$(egrep ^export "$(type -p ghc)")"
|
||||||
fi
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
If you are certain that you'll use only one GHC environment which is located in
|
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
|
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
|
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
|
settings always remain valid even if a `nix-env -u` operation updates the GHC
|
||||||
environment in your profile:
|
environment in your profile:
|
||||||
|
```bash
|
||||||
if [ -e ~/.nix-profile/bin/ghc ]; then
|
if [ -e ~/.nix-profile/bin/ghc ]; then
|
||||||
export NIX_GHC="$HOME/.nix-profile/bin/ghc"
|
export NIX_GHC="$HOME/.nix-profile/bin/ghc"
|
||||||
export NIX_GHCPKG="$HOME/.nix-profile/bin/ghc-pkg"
|
export NIX_GHCPKG="$HOME/.nix-profile/bin/ghc-pkg"
|
||||||
export NIX_GHC_DOCDIR="$HOME/.nix-profile/share/doc/ghc/html"
|
export NIX_GHC_DOCDIR="$HOME/.nix-profile/share/doc/ghc/html"
|
||||||
export NIX_GHC_LIBDIR="$HOME/.nix-profile/lib/ghc-$($NIX_GHC --numeric-version)"
|
export NIX_GHC_LIBDIR="$HOME/.nix-profile/lib/ghc-$($NIX_GHC --numeric-version)"
|
||||||
fi
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
### How to install a compiler with libraries, hoogle and documentation indexes
|
### How to install a compiler with libraries, hoogle and documentation indexes
|
||||||
|
|
||||||
|
@ -280,8 +295,8 @@ uses all those things. A precise name for this thing would be
|
||||||
long and scary.
|
long and scary.
|
||||||
|
|
||||||
For example, installing the following environment
|
For example, installing the following environment
|
||||||
|
```nix
|
||||||
{
|
{
|
||||||
packageOverrides = super: let self = super.pkgs; in
|
packageOverrides = super: let self = super.pkgs; in
|
||||||
{
|
{
|
||||||
myHaskellEnv = self.haskellPackages.ghcWithHoogle
|
myHaskellEnv = self.haskellPackages.ghcWithHoogle
|
||||||
|
@ -292,8 +307,8 @@ For example, installing the following environment
|
||||||
cabal-install haskintex
|
cabal-install haskintex
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
```
|
||||||
allows one to browse module documentation index [not too dissimilar to
|
allows one to browse module documentation index [not too dissimilar to
|
||||||
this](https://downloads.haskell.org/~ghc/latest/docs/html/libraries/index.html)
|
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
|
for all the specified packages and their dependencies by directing a browser of
|
||||||
|
@ -303,23 +318,24 @@ choice to `~/.nix-profiles/share/doc/hoogle/index.html` (or
|
||||||
|
|
||||||
After you've marveled enough at that try adding the following to your
|
After you've marveled enough at that try adding the following to your
|
||||||
`~/.ghc/ghci.conf`
|
`~/.ghc/ghci.conf`
|
||||||
|
```
|
||||||
:def hoogle \s -> return $ ":! hoogle search -cl --count=15 \"" ++ s ++ "\""
|
:def hoogle \s -> return $ ":! hoogle search -cl --count=15 \"" ++ s ++ "\""
|
||||||
:def doc \s -> return $ ":! hoogle search -cl --info \"" ++ s ++ "\""
|
:def doc \s -> return $ ":! hoogle search -cl --info \"" ++ s ++ "\""
|
||||||
|
```
|
||||||
and test it by typing into `ghci`:
|
and test it by typing into `ghci`:
|
||||||
|
```
|
||||||
:hoogle a -> a
|
:hoogle a -> a
|
||||||
:doc a -> a
|
:doc a -> a
|
||||||
|
```
|
||||||
|
|
||||||
Be sure to note the links to `haddock` files in the output. With any modern and
|
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
|
properly configured terminal emulator you can just click those links to
|
||||||
navigate there.
|
navigate there.
|
||||||
|
|
||||||
Finally, you can run
|
Finally, you can run
|
||||||
|
```shell
|
||||||
hoogle server -p 8080
|
hoogle server -p 8080
|
||||||
|
```
|
||||||
and navigate to http://localhost:8080/ for your own local
|
and navigate to http://localhost:8080/ for your own local
|
||||||
[Hoogle](https://www.haskell.org/hoogle/). Note, however, that Firefox and
|
[Hoogle](https://www.haskell.org/hoogle/). Note, however, that Firefox and
|
||||||
possibly other browsers disallow navigation from `http:` to `file:` URIs for
|
possibly other browsers disallow navigation from `http:` to `file:` URIs for
|
||||||
|
@ -334,18 +350,20 @@ 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,
|
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
|
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.
|
Internet. Pass the `--nix` flag to any `stack` command to do so, e.g.
|
||||||
|
```shell
|
||||||
$ git clone --recursive http://github.com/yesodweb/wai
|
git clone --recursive http://github.com/yesodweb/wai
|
||||||
$ cd wai
|
cd wai
|
||||||
$ stack --nix build
|
stack --nix build
|
||||||
|
```
|
||||||
|
|
||||||
If you want `stack` to use Nix by default, you can add a `nix` section to the
|
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
|
`stack.yaml` file, as explained in the [Stack documentation][stack-nix-doc]. For
|
||||||
example:
|
example:
|
||||||
|
```yaml
|
||||||
nix:
|
nix:
|
||||||
enable: true
|
enable: true
|
||||||
packages: [pkgconfig zeromq zlib]
|
packages: [pkgconfig zeromq zlib]
|
||||||
|
```
|
||||||
|
|
||||||
The example configuration snippet above tells Stack to create an ad hoc
|
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`,
|
environment for `nix-shell` as in the below section, in which the `pkgconfig`,
|
||||||
|
@ -356,10 +374,11 @@ Some projects have more sophisticated needs. For examples, some ad hoc
|
||||||
environments might need to expose Nixpkgs packages compiled in a certain way, or
|
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
|
with extra environment variables. In these cases, you'll need a `shell` field
|
||||||
instead of `packages`:
|
instead of `packages`:
|
||||||
|
```yaml
|
||||||
nix:
|
nix:
|
||||||
enable: true
|
enable: true
|
||||||
shell-file: shell.nix
|
shell-file: shell.nix
|
||||||
|
```
|
||||||
|
|
||||||
For more on how to write a `shell.nix` file see the below section. You'll need
|
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
|
to express a derivation. Note that Nixpkgs ships with a convenience wrapper
|
||||||
|
@ -368,32 +387,34 @@ 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
|
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
|
including packages that link against a version of the R library compiled with
|
||||||
special options turned on:
|
special options turned on:
|
||||||
|
```nix
|
||||||
|
with (import <nixpkgs> { });
|
||||||
|
|
||||||
with (import <nixpkgs> { });
|
let R = pkgs.R.override { enableStrictBarrier = true; };
|
||||||
|
in
|
||||||
let R = pkgs.R.override { enableStrictBarrier = true; };
|
haskell.lib.buildStackProject {
|
||||||
in
|
|
||||||
haskell.lib.buildStackProject {
|
|
||||||
name = "HaskellR";
|
name = "HaskellR";
|
||||||
buildInputs = [ R zeromq zlib ];
|
buildInputs = [ R zeromq zlib ];
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
You can select a particular GHC version to compile with by setting the
|
You can select a particular GHC version to compile with by setting the
|
||||||
`ghc` attribute as an argument to `buildStackProject`. Better yet, let
|
`ghc` attribute as an argument to `buildStackProject`. Better yet, let
|
||||||
Stack choose what GHC version it wants based on the snapshot specified
|
Stack choose what GHC version it wants based on the snapshot specified
|
||||||
in `stack.yaml` (only works with Stack >= 1.1.3):
|
in `stack.yaml` (only works with Stack >= 1.1.3):
|
||||||
|
```nix
|
||||||
|
{nixpkgs ? import <nixpkgs> { }, ghc ? nixpkgs.ghc}:
|
||||||
|
|
||||||
{nixpkgs ? import <nixpkgs> { }, ghc ? nixpkgs.ghc}:
|
with nixpkgs;
|
||||||
|
|
||||||
with nixpkgs;
|
let R = pkgs.R.override { enableStrictBarrier = true; };
|
||||||
|
in
|
||||||
let R = pkgs.R.override { enableStrictBarrier = true; };
|
haskell.lib.buildStackProject {
|
||||||
in
|
|
||||||
haskell.lib.buildStackProject {
|
|
||||||
name = "HaskellR";
|
name = "HaskellR";
|
||||||
buildInputs = [ R zeromq zlib ];
|
buildInputs = [ R zeromq zlib ];
|
||||||
inherit ghc;
|
inherit ghc;
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
[stack-nix-doc]: http://docs.haskellstack.org/en/stable/nix_integration.html
|
[stack-nix-doc]: http://docs.haskellstack.org/en/stable/nix_integration.html
|
||||||
|
|
||||||
|
@ -401,24 +422,26 @@ in `stack.yaml` (only works with Stack >= 1.1.3):
|
||||||
|
|
||||||
The easiest way to create an ad hoc development environment is to run
|
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:
|
`nix-shell` with the appropriate GHC environment given on the command-line:
|
||||||
|
```shell
|
||||||
nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [mtl pandoc])"
|
nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [mtl pandoc])"
|
||||||
|
```
|
||||||
|
|
||||||
For more sophisticated use-cases, however, it's more convenient to save the
|
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:
|
desired configuration in a file called `shell.nix` that looks like this:
|
||||||
|
```nix
|
||||||
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
||||||
let
|
let
|
||||||
inherit (nixpkgs) pkgs;
|
inherit (nixpkgs) pkgs;
|
||||||
ghc = pkgs.haskell.packages.${compiler}.ghcWithPackages (ps: with ps; [
|
ghc = pkgs.haskell.packages.${compiler}.ghcWithPackages (ps: with ps; [
|
||||||
monad-par mtl
|
monad-par mtl
|
||||||
]);
|
]);
|
||||||
in
|
in
|
||||||
pkgs.stdenv.mkDerivation {
|
pkgs.stdenv.mkDerivation {
|
||||||
name = "my-haskell-env-0";
|
name = "my-haskell-env-0";
|
||||||
buildInputs = [ ghc ];
|
buildInputs = [ ghc ];
|
||||||
shellHook = "eval $(egrep ^export ${ghc}/bin/ghc)";
|
shellHook = "eval $(egrep ^export ${ghc}/bin/ghc)";
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Now run `nix-shell` --- or even `nix-shell --pure` --- to enter a shell
|
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`,
|
environment that has the appropriate compiler in `$PATH`. If you use `--pure`,
|
||||||
|
@ -434,13 +457,14 @@ already! Every Haskell package has an `env` attribute that provides a shell
|
||||||
environment suitable for compiling that particular package. If you'd like to
|
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
|
hack the `lens` library, for example, then you just have to check out the
|
||||||
source code and enter the appropriate environment:
|
source code and enter the appropriate environment:
|
||||||
|
```
|
||||||
|
$ cabal get lens-4.11 && cd lens-4.11
|
||||||
|
Downloading lens-4.11...
|
||||||
|
Unpacking to lens-4.11/
|
||||||
|
|
||||||
$ cabal get lens-4.11 && cd lens-4.11
|
$ nix-shell "<nixpkgs>" -A haskellPackages.lens.env
|
||||||
Downloading lens-4.11...
|
[nix-shell:/tmp/lens-4.11]$
|
||||||
Unpacking to lens-4.11/
|
```
|
||||||
|
|
||||||
$ nix-shell "<nixpkgs>" -A haskellPackages.lens.env
|
|
||||||
[nix-shell:/tmp/lens-4.11]$
|
|
||||||
|
|
||||||
At point, you can run `cabal configure`, `cabal build`, and all the other
|
At point, you can run `cabal configure`, `cabal build`, and all the other
|
||||||
development commands. Note that you need `cabal-install` installed in your
|
development commands. Note that you need `cabal-install` installed in your
|
||||||
|
@ -459,18 +483,20 @@ convert those automatically into build instructions for Nix using the
|
||||||
For example, let's assume that you're working on a private project called
|
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
|
`foo`. To generate a Nix build expression for it, change into the project's
|
||||||
top-level directory and run the command:
|
top-level directory and run the command:
|
||||||
|
```shell
|
||||||
$ cabal2nix . >foo.nix
|
cabal2nix . > foo.nix
|
||||||
|
```
|
||||||
Then write the following snippet into a file called `default.nix`:
|
Then write the following snippet into a file called `default.nix`:
|
||||||
|
```nix
|
||||||
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
||||||
nixpkgs.pkgs.haskell.packages.${compiler}.callPackage ./foo.nix { }
|
nixpkgs.pkgs.haskell.packages.${compiler}.callPackage ./foo.nix { }
|
||||||
|
```
|
||||||
|
|
||||||
Finally, store the following code in a file called `shell.nix`:
|
Finally, store the following code in a file called `shell.nix`:
|
||||||
|
```nix
|
||||||
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc7102" }:
|
||||||
(import ./default.nix { inherit nixpkgs compiler; }).env
|
(import ./default.nix { inherit nixpkgs compiler; }).env
|
||||||
|
```
|
||||||
|
|
||||||
At this point, you can run `nix-build` to have Nix compile your project and
|
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
|
install it into a Nix store path. The local directory will contain a symlink
|
||||||
|
@ -486,9 +512,9 @@ libraries your package might need.
|
||||||
|
|
||||||
If your package does not depend on any system-level libraries, then it's
|
If your package does not depend on any system-level libraries, then it's
|
||||||
sufficient to run
|
sufficient to run
|
||||||
|
```shell
|
||||||
$ nix-shell --command "cabal configure"
|
nix-shell --command "cabal configure"
|
||||||
|
```
|
||||||
once to set up your build. `cabal-install` determines the absolute paths to all
|
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
|
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
|
`dist/` directory. Once that's done, you can run `cabal build` and any other
|
||||||
|
@ -502,14 +528,15 @@ 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
|
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
|
`--shell` flag offered by `cabal2nix` to have it generate a stand-alone
|
||||||
`nix-shell` environment for you. With that feature, running
|
`nix-shell` environment for you. With that feature, running
|
||||||
|
```shell
|
||||||
$ cabal2nix --shell . >shell.nix
|
cabal2nix --shell . > shell.nix
|
||||||
$ nix-shell --command "cabal configure"
|
nix-shell --command "cabal configure"
|
||||||
|
```
|
||||||
is usually enough to set up a build environment for any given Haskell package.
|
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:
|
You can even use that generated file to run `nix-build`, too:
|
||||||
|
```shell
|
||||||
$ nix-build shell.nix
|
nix-build shell.nix
|
||||||
|
```
|
||||||
|
|
||||||
### How to build projects that depend on each other
|
### How to build projects that depend on each other
|
||||||
|
|
||||||
|
@ -518,14 +545,14 @@ 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
|
for the dependency resolution performed by `callPackage`. First of all, change
|
||||||
into each of your projects top-level directories and generate a `default.nix`
|
into each of your projects top-level directories and generate a `default.nix`
|
||||||
file with `cabal2nix`:
|
file with `cabal2nix`:
|
||||||
|
```shell
|
||||||
$ cd ~/src/foo && cabal2nix . >default.nix
|
cd ~/src/foo && cabal2nix . > default.nix
|
||||||
$ cd ~/src/bar && cabal2nix . >default.nix
|
cd ~/src/bar && cabal2nix . > default.nix
|
||||||
|
```
|
||||||
Then edit your `~/.config/nixpkgs/config.nix` file to register those builds in the
|
Then edit your `~/.config/nixpkgs/config.nix` file to register those builds in the
|
||||||
default Haskell package set:
|
default Haskell package set:
|
||||||
|
```nix
|
||||||
{
|
{
|
||||||
packageOverrides = super: let self = super.pkgs; in
|
packageOverrides = super: let self = super.pkgs; in
|
||||||
{
|
{
|
||||||
haskellPackages = super.haskellPackages.override {
|
haskellPackages = super.haskellPackages.override {
|
||||||
|
@ -535,16 +562,17 @@ default Haskell package set:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
```
|
||||||
Once that's accomplished, `nix-env -f "<nixpkgs>" -qA haskellPackages` will
|
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
|
show your packages like any other package from Hackage, and you can build them
|
||||||
|
```shell
|
||||||
$ nix-build "<nixpkgs>" -A haskellPackages.foo
|
nix-build "<nixpkgs>" -A haskellPackages.foo
|
||||||
|
```
|
||||||
or enter an interactive shell environment suitable for building them:
|
or enter an interactive shell environment suitable for building them:
|
||||||
|
```shell
|
||||||
$ nix-shell "<nixpkgs>" -A haskellPackages.bar.env
|
nix-shell "<nixpkgs>" -A haskellPackages.bar.env
|
||||||
|
```
|
||||||
|
|
||||||
## Miscellaneous Topics
|
## Miscellaneous Topics
|
||||||
|
|
||||||
|
@ -555,8 +583,8 @@ 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
|
feature is to replace the default `mkDerivation` function with one that enables
|
||||||
library profiling for all packages. To accomplish that, add configure the
|
library profiling for all packages. To accomplish that, add configure the
|
||||||
following snippet in your `~/.config/nixpkgs/config.nix` file:
|
following snippet in your `~/.config/nixpkgs/config.nix` file:
|
||||||
|
```nix
|
||||||
{
|
{
|
||||||
packageOverrides = super: let self = super.pkgs; in
|
packageOverrides = super: let self = super.pkgs; in
|
||||||
{
|
{
|
||||||
profiledHaskellPackages = self.haskellPackages.override {
|
profiledHaskellPackages = self.haskellPackages.override {
|
||||||
|
@ -567,8 +595,8 @@ following snippet in your `~/.config/nixpkgs/config.nix` file:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
```
|
||||||
Then, replace instances of `haskellPackages` in the `cabal2nix`-generated
|
Then, replace instances of `haskellPackages` in the `cabal2nix`-generated
|
||||||
`default.nix` or `shell.nix` files with `profiledHaskellPackages`.
|
`default.nix` or `shell.nix` files with `profiledHaskellPackages`.
|
||||||
|
|
||||||
|
@ -580,12 +608,12 @@ 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
|
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.
|
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`:
|
The first step is to generate Nix build instructions with `cabal2nix`:
|
||||||
|
```shell
|
||||||
$ cabal2nix cabal://ghc-events-0.4.3.0 >~/.nixpkgs/ghc-events-0.4.3.0.nix
|
cabal2nix cabal://ghc-events-0.4.3.0 > ~/.nixpkgs/ghc-events-0.4.3.0.nix
|
||||||
|
```
|
||||||
Then add the override in `~/.config/nixpkgs/config.nix`:
|
Then add the override in `~/.config/nixpkgs/config.nix`:
|
||||||
|
```nix
|
||||||
{
|
{
|
||||||
packageOverrides = super: let self = super.pkgs; in
|
packageOverrides = super: let self = super.pkgs; in
|
||||||
{
|
{
|
||||||
haskell = super.haskell // {
|
haskell = super.haskell // {
|
||||||
|
@ -598,17 +626,21 @@ Then add the override in `~/.config/nixpkgs/config.nix`:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
This code is a little crazy, no doubt, but it's necessary because the intuitive
|
This code is a little crazy, no doubt, but it's necessary because the intuitive
|
||||||
version
|
version
|
||||||
|
```nix
|
||||||
|
{ # ...
|
||||||
|
|
||||||
haskell.packages.ghc784 = super.haskell.packages.ghc784.override {
|
haskell.packages.ghc784 = super.haskell.packages.ghc784.override {
|
||||||
overrides = self: super: {
|
overrides = self: super: {
|
||||||
ghc-events = self.callPackage ./ghc-events-0.4.3.0.nix {};
|
ghc-events = self.callPackage ./ghc-events-0.4.3.0.nix {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
doesn't do what we want it to: that code replaces the `haskell` package set in
|
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
|
Nixpkgs with one that contains only one entry,`packages`, which contains only
|
||||||
one entry `ghc784`. This override loses the `haskell.compiler` set, and it
|
one entry `ghc784`. This override loses the `haskell.compiler` set, and it
|
||||||
|
@ -618,16 +650,16 @@ iterating over each step in hierarchy.
|
||||||
|
|
||||||
Once it's accomplished, however, we can install a variant of `ghc-events`
|
Once it's accomplished, however, we can install a variant of `ghc-events`
|
||||||
that's compiled with GHC 7.8.4:
|
that's compiled with GHC 7.8.4:
|
||||||
|
```shell
|
||||||
nix-env -f "<nixpkgs>" -iA haskell.packages.ghc784.ghc-events
|
nix-env -f "<nixpkgs>" -iA haskell.packages.ghc784.ghc-events
|
||||||
|
```
|
||||||
Unfortunately, it turns out that this build fails again while executing the
|
Unfortunately, it turns out that this build fails again while executing the
|
||||||
test suite! Apparently, the release archive on Hackage is missing some data
|
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
|
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:
|
re-generating the Nix expression with the `--no-check` flag:
|
||||||
|
```shell
|
||||||
$ cabal2nix --no-check cabal://ghc-events-0.4.3.0 >~/.nixpkgs/ghc-events-0.4.3.0.nix
|
cabal2nix --no-check cabal://ghc-events-0.4.3.0 > ~/.nixpkgs/ghc-events-0.4.3.0.nix
|
||||||
|
```
|
||||||
Now the builds succeeds.
|
Now the builds succeeds.
|
||||||
|
|
||||||
Of course, in the concrete example of `ghc-events` this whole exercise is not
|
Of course, in the concrete example of `ghc-events` this whole exercise is not
|
||||||
|
@ -642,91 +674,98 @@ older version might be useful.
|
||||||
|
|
||||||
GHC and distributed build farms don't get along well:
|
GHC and distributed build farms don't get along well:
|
||||||
|
|
||||||
https://ghc.haskell.org/trac/ghc/ticket/4012
|
- https://ghc.haskell.org/trac/ghc/ticket/4012
|
||||||
|
|
||||||
When you see an error like this one
|
When you see an error like this one
|
||||||
|
```
|
||||||
package foo-0.7.1.0 is broken due to missing package
|
package foo-0.7.1.0 is broken due to missing package
|
||||||
text-1.2.0.4-98506efb1b9ada233bb5c2b2db516d91
|
text-1.2.0.4-98506efb1b9ada233bb5c2b2db516d91
|
||||||
|
```
|
||||||
then you have to download and re-install `foo` and all its dependents from
|
then you have to download and re-install `foo` and all its dependents from
|
||||||
scratch:
|
scratch:
|
||||||
|
```shell
|
||||||
# nix-store -q --referrers /nix/store/*-haskell-text-1.2.0.4 \
|
nix-store -q --referrers /nix/store/*-haskell-text-1.2.0.4 \
|
||||||
| xargs -L 1 nix-store --repair-path
|
| xargs -L 1 nix-store --repair-path
|
||||||
|
```
|
||||||
|
|
||||||
If you're using additional Hydra servers other than `hydra.nixos.org`, then it
|
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
|
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
|
machines to disable these binary channels for the duration of the previous
|
||||||
command, i.e. by running:
|
command, i.e. by running:
|
||||||
|
```shell
|
||||||
rm /nix/var/nix/binary-cache-v3.sqlite
|
rm /nix/var/nix/binary-cache-v3.sqlite
|
||||||
rm /nix/var/nix/manifests/*
|
rm /nix/var/nix/manifests/*
|
||||||
rm /nix/var/nix/channel-cache/*
|
rm /nix/var/nix/channel-cache/*
|
||||||
|
```
|
||||||
|
|
||||||
### How to use the Haste Haskell-to-Javascript transpiler
|
### How to use the Haste Haskell-to-Javascript transpiler
|
||||||
|
|
||||||
Open a shell with `haste-compiler` and `haste-cabal-install` (you don't actually need
|
Open a shell with `haste-compiler` and `haste-cabal-install` (you don't actually need
|
||||||
`node`, but it can be useful to test stuff):
|
`node`, but it can be useful to test stuff):
|
||||||
|
```shell
|
||||||
$ nix-shell -p "haskellPackages.ghcWithPackages (self: with self; [haste-cabal-install haste-compiler])" -p nodejs
|
nix-shell \
|
||||||
|
-p "haskellPackages.ghcWithPackages (self: with self; [haste-cabal-install haste-compiler])" \
|
||||||
|
-p nodejs
|
||||||
|
```
|
||||||
You may not need the following step but if `haste-boot` fails to compile all the
|
You may not need the following step but if `haste-boot` fails to compile all the
|
||||||
packages it needs, this might do the trick
|
packages it needs, this might do the trick
|
||||||
|
```shell
|
||||||
$ haste-cabal update
|
haste-cabal update
|
||||||
|
```
|
||||||
`haste-boot` builds a set of core libraries so that they can be used from Javascript
|
`haste-boot` builds a set of core libraries so that they can be used from Javascript
|
||||||
transpiled programs:
|
transpiled programs:
|
||||||
|
```shell
|
||||||
$ haste-boot
|
haste-boot
|
||||||
|
```
|
||||||
Transpile and run a "Hello world" program:
|
Transpile and run a "Hello world" program:
|
||||||
|
```
|
||||||
$ echo 'module Main where main = putStrLn "Hello world"' > hello-world.hs
|
$ echo 'module Main where main = putStrLn "Hello world"' > hello-world.hs
|
||||||
$ hastec --onexec hello-world.hs
|
$ hastec --onexec hello-world.hs
|
||||||
$ node hello-world.js
|
$ node hello-world.js
|
||||||
Hello world
|
Hello world
|
||||||
|
```
|
||||||
|
|
||||||
### Builds on Darwin fail with `math.h` not found
|
### Builds on Darwin fail with `math.h` not found
|
||||||
|
|
||||||
Users of GHC on Darwin have occasionally reported that builds fail, because the
|
Users of GHC on Darwin have occasionally reported that builds fail, because the
|
||||||
compiler complains about a missing include file:
|
compiler complains about a missing include file:
|
||||||
|
```
|
||||||
fatal error: 'math.h' file not found
|
fatal error: 'math.h' file not found
|
||||||
|
```
|
||||||
The issue has been discussed at length in [ticket
|
The issue has been discussed at length in [ticket
|
||||||
6390](https://github.com/NixOS/nixpkgs/issues/6390), and so far no good
|
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
|
solution has been proposed. As a work-around, users who run into this problem
|
||||||
can configure the environment variables
|
can configure the environment variables
|
||||||
|
```shell
|
||||||
export NIX_CFLAGS_COMPILE="-idirafter /usr/include"
|
export NIX_CFLAGS_COMPILE="-idirafter /usr/include"
|
||||||
export NIX_CFLAGS_LINK="-L/usr/lib"
|
export NIX_CFLAGS_LINK="-L/usr/lib"
|
||||||
|
```
|
||||||
in their `~/.bashrc` file to avoid the compiler error.
|
in their `~/.bashrc` file to avoid the compiler error.
|
||||||
|
|
||||||
### Builds using Stack complain about missing system libraries
|
### Builds using Stack complain about missing system libraries
|
||||||
|
|
||||||
-- While building package zlib-0.5.4.2 using:
|
```
|
||||||
|
-- While building package zlib-0.5.4.2 using:
|
||||||
runhaskell -package=Cabal-1.22.4.0 -clear-package-db [... lots of flags ...]
|
runhaskell -package=Cabal-1.22.4.0 -clear-package-db [... lots of flags ...]
|
||||||
Process exited with code: ExitFailure 1
|
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
|
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...
|
Configuring zlib-0.5.4.2...
|
||||||
Setup.hs: Missing dependency on a foreign library:
|
Setup.hs: Missing dependency on a foreign library:
|
||||||
* Missing (or bad) header file: zlib.h
|
* Missing (or bad) header file: zlib.h
|
||||||
This problem can usually be solved by installing the system package that
|
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
|
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
|
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.
|
--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
|
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
|
compiler at the preprocessing stage. In this case you can re-run configure
|
||||||
with the verbosity flag -v3 to see the error messages.
|
with the verbosity flag -v3 to see the error messages.
|
||||||
|
```
|
||||||
|
|
||||||
When you run the build inside of the nix-shell environment, the system
|
When you run the build inside of the nix-shell environment, the system
|
||||||
is configured to find libz.so without any special flags -- the compiler
|
is configured to find `libz.so` without any special flags -- the compiler
|
||||||
and linker "just know" how to find it. Consequently, Cabal won't record
|
and linker "just know" how to find it. Consequently, Cabal won't record
|
||||||
any search paths for libz.so in the package description, which means
|
any search paths for `libz.so` in the package description, which means
|
||||||
that the package works fine inside of nix-shell, but once you leave the
|
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
|
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
|
means specific to Stack: you'll have that problem with any other
|
||||||
|
@ -735,39 +774,41 @@ environment.
|
||||||
|
|
||||||
You can remedy this issue in several ways. The easiest is to add a `nix` section
|
You can remedy this issue in several ways. The easiest is to add a `nix` section
|
||||||
to the `stack.yaml` like the following:
|
to the `stack.yaml` like the following:
|
||||||
|
```yaml
|
||||||
nix:
|
nix:
|
||||||
enable: true
|
enable: true
|
||||||
packages: [ zlib ]
|
packages: [ zlib ]
|
||||||
|
```
|
||||||
|
|
||||||
Stack's Nix support knows to add `${zlib.out}/lib` and `${zlib.dev}/include` as an
|
Stack's Nix support knows to add `${zlib.out}/lib` and `${zlib.dev}/include`
|
||||||
`--extra-lib-dirs` and `extra-include-dirs`, respectively. Alternatively, you
|
as an `--extra-lib-dirs` and `extra-include-dirs`, respectively.
|
||||||
can achieve the same effect by hand. First of all, run
|
Alternatively, you can achieve the same effect by hand. First of all, run
|
||||||
|
```
|
||||||
$ nix-build --no-out-link "<nixpkgs>" -A zlib
|
$ nix-build --no-out-link "<nixpkgs>" -A zlib
|
||||||
/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8
|
/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8
|
||||||
|
```
|
||||||
to find out the store path of the system's zlib library. Now, you can
|
to find out the store path of the system's zlib library. Now, you can
|
||||||
|
|
||||||
1) add that path (plus a "/lib" suffix) to your $LD_LIBRARY_PATH
|
1. add that path (plus a "/lib" suffix) to your `$LD_LIBRARY_PATH`
|
||||||
environment variable to make sure your system linker finds libz.so
|
environment variable to make sure your system linker finds `libz.so`
|
||||||
automatically. It's no pretty solution, but it will work.
|
automatically. It's no pretty solution, but it will work.
|
||||||
|
|
||||||
2) As a variant of (1), you can also install any number of system
|
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
|
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
|
`$LD_LIBRARY_PATH` to that profile instead, so that you don't have to
|
||||||
list dozens of those store paths all over the place.
|
list dozens of those store paths all over the place.
|
||||||
|
|
||||||
3) The solution I prefer is to call stack with an appropriate
|
3. The solution I prefer is to call stack with an appropriate
|
||||||
--extra-lib-dirs flag like so:
|
--extra-lib-dirs flag like so:
|
||||||
|
```shell
|
||||||
|
stack --extra-lib-dirs=/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8/lib build
|
||||||
|
```
|
||||||
|
|
||||||
$ stack --extra-lib-dirs=/nix/store/alsvwzkiw4b7ip38l4nlfjijdvg3fvzn-zlib-1.2.8/lib build
|
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
|
||||||
Typically, you'll need --extra-include-dirs as well. It's possible
|
global `~/.stack/global/stack.yaml` file so that you don't have to
|
||||||
to add those flag to the project's "stack.yaml" or your user's
|
specify them manually every time. But again, you're likely better off
|
||||||
global "~/.stack/global/stack.yaml" file so that you don't have to
|
using Stack's Nix support instead.
|
||||||
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
|
The same thing applies to `cabal configure`, of course, if you're
|
||||||
building with `cabal-install` instead of Stack.
|
building with `cabal-install` instead of Stack.
|
||||||
|
@ -777,21 +818,22 @@ to find out the store path of the system's zlib library. Now, you can
|
||||||
There are two levels of static linking. The first option is to configure the
|
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,
|
build with the Cabal flag `--disable-executable-dynamic`. In Nix expressions,
|
||||||
this can be achieved by setting the attribute:
|
this can be achieved by setting the attribute:
|
||||||
|
```
|
||||||
enableSharedExecutables = false;
|
enableSharedExecutables = false;
|
||||||
|
```
|
||||||
That gives you a binary with statically linked Haskell libraries and
|
That gives you a binary with statically linked Haskell libraries and
|
||||||
dynamically linked system libraries.
|
dynamically linked system libraries.
|
||||||
|
|
||||||
To link both Haskell libraries and system libraries statically, the additional
|
To link both Haskell libraries and system libraries statically, the additional
|
||||||
flags `--ghc-option=-optl=-static --ghc-option=-optl=-pthread` need to be used.
|
flags `--ghc-option=-optl=-static --ghc-option=-optl=-pthread` need to be used.
|
||||||
In Nix, this is accomplished with:
|
In Nix, this is accomplished with:
|
||||||
|
```
|
||||||
|
configureFlags = [ "--ghc-option=-optl=-static" "--ghc-option=-optl=-pthread" ];
|
||||||
|
```
|
||||||
|
|
||||||
configureFlags = [ "--ghc-option=-optl=-static" "--ghc-option=-optl=-pthread" ];
|
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
|
||||||
It's important to realize, however, that most system libraries in Nix are built
|
available that Cabal could link!
|
||||||
as shared libraries only, i.e. there is just no static library available that
|
|
||||||
Cabal could link!
|
|
||||||
|
|
||||||
### Building GHC with integer-simple
|
### Building GHC with integer-simple
|
||||||
|
|
||||||
|
@ -801,7 +843,7 @@ The implementation can be found in the
|
||||||
[integer-gmp](http://hackage.haskell.org/package/integer-gmp) package.
|
[integer-gmp](http://hackage.haskell.org/package/integer-gmp) package.
|
||||||
|
|
||||||
A potential problem with this is that GMP is licensed under the
|
A potential problem with this is that GMP is licensed under the
|
||||||
[GNU Lesser General Public License (LGPL)](http://www.gnu.org/copyleft/lesser.html),
|
[GNU Lesser General Public License (LGPL)](http://www.gnu.org/copyleft/lesser.html),
|
||||||
a kind of "copyleft" license. According to the terms of the LGPL, paragraph 5,
|
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
|
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
|
linked with the library under the terms of your choice (i.e., commercially) but
|
||||||
|
@ -814,7 +856,7 @@ 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
|
programs compiled with GHC because most distributions (and builds) of GHC use
|
||||||
static libraries. (Dynamic libraries are currently distributed only for OS X.)
|
static libraries. (Dynamic libraries are currently distributed only for OS X.)
|
||||||
The LGPL licensing situation may be worse: even though
|
The LGPL licensing situation may be worse: even though
|
||||||
[The Glasgow Haskell Compiler License](https://www.haskell.org/ghc/license)
|
[The Glasgow Haskell Compiler License](https://www.haskell.org/ghc/license)
|
||||||
is essentially a "free software" license (BSD3), according to
|
is essentially a "free software" license (BSD3), according to
|
||||||
paragraph 2 of the LGPL, GHC must be distributed under the terms of the LGPL!
|
paragraph 2 of the LGPL, GHC must be distributed under the terms of the LGPL!
|
||||||
|
|
||||||
|
@ -825,48 +867,49 @@ alternative implemention for Integer called
|
||||||
To get a GHC compiler build with `integer-simple` instead of `integer-gmp` use
|
To get a GHC compiler build with `integer-simple` instead of `integer-gmp` use
|
||||||
the attribute: `haskell.compiler.integer-simple."${ghcVersion}"`.
|
the attribute: `haskell.compiler.integer-simple."${ghcVersion}"`.
|
||||||
For example:
|
For example:
|
||||||
|
```
|
||||||
$ nix-build -E '(import <nixpkgs> {}).haskell.compiler.integer-simple.ghc802'
|
$ nix-build -E '(import <nixpkgs> {}).haskell.compiler.integer-simple.ghc802'
|
||||||
...
|
...
|
||||||
$ result/bin/ghc-pkg list | grep integer
|
$ result/bin/ghc-pkg list | grep integer
|
||||||
integer-simple-0.1.1.1
|
integer-simple-0.1.1.1
|
||||||
|
```
|
||||||
The following command displays the complete list of GHC compilers build with `integer-simple`:
|
The following command displays the complete list of GHC compilers build with `integer-simple`:
|
||||||
|
```
|
||||||
$ nix-env -f "<nixpkgs>" -qaP -A haskell.compiler.integer-simple
|
$ nix-env -f "<nixpkgs>" -qaP -A haskell.compiler.integer-simple
|
||||||
haskell.compiler.integer-simple.ghc7102 ghc-7.10.2
|
haskell.compiler.integer-simple.ghc7102 ghc-7.10.2
|
||||||
haskell.compiler.integer-simple.ghc7103 ghc-7.10.3
|
haskell.compiler.integer-simple.ghc7103 ghc-7.10.3
|
||||||
haskell.compiler.integer-simple.ghc722 ghc-7.2.2
|
haskell.compiler.integer-simple.ghc722 ghc-7.2.2
|
||||||
haskell.compiler.integer-simple.ghc742 ghc-7.4.2
|
haskell.compiler.integer-simple.ghc742 ghc-7.4.2
|
||||||
haskell.compiler.integer-simple.ghc783 ghc-7.8.3
|
haskell.compiler.integer-simple.ghc783 ghc-7.8.3
|
||||||
haskell.compiler.integer-simple.ghc784 ghc-7.8.4
|
haskell.compiler.integer-simple.ghc784 ghc-7.8.4
|
||||||
haskell.compiler.integer-simple.ghc801 ghc-8.0.1
|
haskell.compiler.integer-simple.ghc801 ghc-8.0.1
|
||||||
haskell.compiler.integer-simple.ghc802 ghc-8.0.2
|
haskell.compiler.integer-simple.ghc802 ghc-8.0.2
|
||||||
haskell.compiler.integer-simple.ghcHEAD ghc-8.1.20170106
|
haskell.compiler.integer-simple.ghcHEAD ghc-8.1.20170106
|
||||||
|
```
|
||||||
|
|
||||||
To get a package set supporting `integer-simple` use the attribute:
|
To get a package set supporting `integer-simple` use the attribute:
|
||||||
`haskell.packages.integer-simple."${ghcVersion}"`. For example
|
`haskell.packages.integer-simple."${ghcVersion}"`. For example
|
||||||
use the following to get the `scientific` package build with `integer-simple`:
|
use the following to get the `scientific` package build with `integer-simple`:
|
||||||
|
```shell
|
||||||
$ nix-build -A haskell.packages.integer-simple.ghc802.scientific
|
nix-build -A haskell.packages.integer-simple.ghc802.scientific
|
||||||
|
```
|
||||||
|
|
||||||
## Other resources
|
## Other resources
|
||||||
|
|
||||||
- The Youtube video [Nix Loves Haskell](https://www.youtube.com/watch?v=BsBhi_r-OeE)
|
- 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
|
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
|
available at http://cryp.to/nixos-meetup-3-slides.pdf and also -- in a form
|
||||||
ready for cut & paste -- at
|
ready for cut & paste -- at
|
||||||
https://github.com/NixOS/cabal2nix/blob/master/doc/nixos-meetup-3-slides.md.
|
https://github.com/NixOS/cabal2nix/blob/master/doc/nixos-meetup-3-slides.md.
|
||||||
|
|
||||||
- Another Youtube video is [Escaping Cabal Hell with Nix](https://www.youtube.com/watch?v=mQd3s57n_2Y),
|
- 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
|
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
|
a basic introduction to Nix as well, i.e. it's suitable for viewers with
|
||||||
almost no prior Nix experience.
|
almost no prior Nix experience.
|
||||||
|
|
||||||
- Oliver Charles wrote a very nice [Tutorial how to develop Haskell packages with Nix](http://wiki.ocharles.org.uk/Nix).
|
- Oliver Charles wrote a very nice [Tutorial how to develop Haskell packages with Nix](http://wiki.ocharles.org.uk/Nix).
|
||||||
|
|
||||||
- The *Journey into the Haskell NG infrastructure* series of postings
|
- The *Journey into the Haskell NG infrastructure* series of postings
|
||||||
describe the new Haskell infrastructure in great detail:
|
describe the new Haskell infrastructure in great detail:
|
||||||
|
|
||||||
- [Part 1](http://lists.science.uu.nl/pipermail/nix-dev/2015-January/015591.html)
|
- [Part 1](http://lists.science.uu.nl/pipermail/nix-dev/2015-January/015591.html)
|
||||||
|
|
Loading…
Reference in a new issue