Skip to content

Commit 360e65d

Browse files
committed
Another update of the docs
1 parent 076417c commit 360e65d

File tree

8 files changed

+404
-15
lines changed

8 files changed

+404
-15
lines changed

changelog.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
This file contains a summary of changes to Haskell.nix and `nix-tools`
22
that will impact users.
33

4-
## June 6, 2019
5-
* Substantial additions to the [documentation](https://input-output-hk.github.io/haskell.nix/).
4+
## June 7, 2019
5+
* Several additions to the [documentation](https://input-output-hk.github.io/haskell.nix/).
6+
* More information about getting nix-tools, Haskell.nix, pinning.
7+
* Updates the stack-to-nix and cabal-to-nix guides.
8+
* Adds a section on development environments.
9+
* Adds a little information about cross compilation.
10+
* Adds a (partially complete) reference section (command line manuals, library reference).
11+
* Symlinks the changelog into the documentation pages.
612

713
## May 29, 2019
814
* Added `shellFor` function to package set.

docs/reference/commands.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# stack-to-nix
2+
3+
```
4+
stack-to-nix - a stack to nix converter
5+
6+
Usage: stack-to-nix (-o|--output DIR) [--stack-yaml FILE]
7+
[--ignore-package-yaml] [--cache FILE]
8+
Generate a Nix expression for a Haskell package using Stack
9+
10+
Available options:
11+
-o,--output DIR Generate output in DIR
12+
--stack-yaml FILE Override project stack.yaml (default: "stack.yaml")
13+
--ignore-package-yaml disable hpack run and use only cabal disregarding
14+
package.yaml existence
15+
--cache FILE Dependency cache
16+
file (default: ".stack-to-nix.cache")
17+
-h,--help Show this help text
18+
```
19+
20+
Use this for stack projects. If a `default.nix` does not exist in the
21+
output directory, it will create a basic one with a
22+
[`mkStackPkgSet`](../user-guide/stack-projects.md) function.
23+
24+
!!! note
25+
If you find that there are missing files which should have been
26+
generated, remove `.stack-to-nix.cache`. (There's an open issue for
27+
this).
28+
29+
# plan-to-nix
30+
31+
```
32+
plan-to-nix - a stack to nix converter
33+
34+
Usage: plan-to-nix (-o|--output DIR) [--plan-json FILE] [--cabal-project FILE]
35+
[--cache FILE]
36+
Generate a Nix expression for a Haskell package using Cabal
37+
38+
Available options:
39+
-o,--output DIR Generate output in DIR
40+
--plan-json FILE Override plan.json
41+
location (default: "dist-newstyle/cache/plan.json")
42+
--cabal-project FILE Override path to
43+
cabal.project (default: "cabal.project")
44+
--cache FILE Dependency cache file (default: ".nix-tools.cache")
45+
-h,--help Show this help text
46+
```
47+
48+
Use this for Cabal new-build projects (even if you don't have a
49+
`cabal.project`). Before running, you need to create a plan. For more
50+
information, see [Cabal Projects](../user-guide/cabal-projects.md) in the user
51+
guide.
52+
53+
It will create a template `default.nix` in the output directory,
54+
unless that file already exists.
55+
56+
Inside the output directory, there will be another directory
57+
`.plan.nix`, which contains Nix expressions for all local packages,
58+
generated by `cabal-to-nix`. The output file `pkgs.nix` refers to
59+
these files.
60+
61+
Same note as above applies about the cache file.
62+
63+
# cabal-to-nix
64+
65+
```
66+
Usage: cabal-to-nix FILE.cabal
67+
```
68+
69+
This writes (to stdout) a [Haskell.nix][] Nix expression for the given
70+
cabal package.
71+
72+
Normally, you do not need to run `cabal-to-nix` yourself. It is called
73+
by `stack-to-nix` and `plan-to-nix`.
74+
75+
[haskell.nix]: https://github.com/input-output-hk/haskell.nix

docs/reference/library.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
[Haskell.nix][] contains a library of functions for creating buildable
2+
package sets from their Nix expression descriptions. The library is
3+
what you get when importing [Haskell.nix][]. It might be helpful to
4+
load the library in the [Nix REPL](../user-guide.md#using-nix-repl) to
5+
test things.
6+
7+
# Types
8+
9+
## Package Set
10+
11+
The result of `mkPkgSet`. This is an application of the NixOS module
12+
system.
13+
14+
```
15+
{
16+
options = { ... };
17+
config = {
18+
hsPkgs = { ... };
19+
packages = { ... };
20+
compiler = {
21+
version = "X.Y.Z";
22+
nix-name = "ghcXYZ";
23+
packages = { ... };
24+
};
25+
};
26+
}
27+
```
28+
29+
| Attribute | Type | Description |
30+
|----------------|------|-----------------------------------------------------|
31+
| `options` | Module options | The combination of all options set through the `modules` argument passed to `mkPkgsSet`. |
32+
| `config` | | The result of evaluating and applying the `options` with [Haskell.nix][] |
33+
| `.hsPkgs` | Attrset of [Haskell Packages](#haskell-package) | Buildable packages, created from `packages` |
34+
| `.packages` | Attrset of [Haskell Package descriptions](#haskell-package-descriptions) | Configuration for each package in `hsPkgs` |
35+
| `.compiler` | Attrset | |
36+
37+
38+
39+
## Haskell Package description
40+
41+
Options for building a package. (todo: more info)
42+
43+
## Component description
44+
45+
Options for building a component. (todo: more info)
46+
47+
## Haskell Package
48+
49+
A derivation which has a `components` attribute. This derivation is
50+
actually just for the package `Setup.hs` script, and isn't very
51+
interesting. To actually use the package, look within the components
52+
structure.
53+
54+
```
55+
components = {
56+
library = COMPONENT;
57+
exes = { NAME = COMPONENT; };
58+
tests = { NAME = COMPONENT; };
59+
benchmarks = { NAME = COMPONENT; };
60+
all = COMPONENT;
61+
}
62+
```
63+
64+
## Component
65+
66+
## Identifier
67+
68+
A package identifier is an attrset pair of `name` and `version`.
69+
70+
## Extras
71+
72+
## Modules
73+
74+
# Top-level attributes
75+
76+
## mkPkgSet
77+
78+
**Return value**: a [`pkgSet`](#package-set)
79+
80+
## mkStackPkgSet
81+
82+
Creates a [package set](#package-set) based on the `pkgs.nix` output
83+
of `stack-to-nix`.
84+
85+
```nix
86+
mkStackPkgSet =
87+
{ stack-pkgs, pkg-def-extras ? [], modules ? []}: ...
88+
```
89+
90+
| Argument | Type | Description |
91+
|------------------|------|---------------------|
92+
| `stack-pkgs` | Path | Path to the `pkgs.nix` generated by `stack-to-nix`. |
93+
| `pkg-def-extras` | List of [Extras](#extras) | For overriding the package set. |
94+
| `modules` | List of [Modules](#modules) | For overriding the package set. |
95+
96+
**Return value**: a [`pkgSet`](#package-set)
97+
98+
## mkCabalProjectPkgSet
99+
100+
## snapshots
101+
102+
This is an attrset of `hsPkgs` packages from Stackage.
103+
104+
## haskellPackages
105+
106+
A `hsPkgs` package set
107+
108+
## nix-tools
109+
110+
A derivation containing the `nix-tools` [command-line tools](commands.md).
111+
112+
## callStackToNix
113+
114+
## callCabalProjectToNix
115+
116+
## hackage
117+
## stackage
118+
119+
## fetchExternal
120+
121+
## cleanSourceHaskell
122+
123+
## haskellLib
124+
125+
# Package-set functions
126+
127+
These functions exist within the `hsPkgs` package set.
128+
129+
## shellFor
130+
131+
Create a `nix-shell` [development
132+
environment](../user-guide/development.md) *for* developing one or
133+
more packages.
134+
135+
```
136+
shellFor =
137+
{ packages, withHoogle ? true, ...}: ...
138+
```
139+
140+
141+
| Argument | Type | Description |
142+
|----------------|------|---------------------|
143+
| `packages` | Function | Package selection function. It takes a list of [Haskell packages](#haskell-package) and returns a subset of these packages. |
144+
| `withHoogle` | Boolean | Whether to build a Hoogle documentation index and provide the `hoogle` command. |
145+
| `{ ... }` | Attrset | All the other arguments are passed to [`mkDerivation`](https://nixos.org/nixpkgs/manual/#sec-using-stdenv). |
146+
147+
**Return value**: a derivation
148+
149+
## ghcWithPackages
150+
151+
## ghcWithHoogle
152+
153+
154+
[haskell.nix]: https://github.com/input-output-hk/haskell.nix

docs/user-guide/cabal-projects.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,25 @@ It has converted Cabal's build plan into a Nix expression that selects
5858
dependencies from `hackage.nix`. All local packages in the project are
5959
generated with `cabal-to-nix` and added to the package set
6060
description.
61+
62+
## Creating the package set
63+
64+
Import the generated `pkgs.nix` and pass to
65+
[`mkCabalPkgSet`](../reference/library.md#mkCabalProjectPkgSet) to
66+
instantiate a package set.
67+
68+
```nix
69+
# default.nix
70+
let
71+
# Import the Haskell.nix library,
72+
haskell = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz) {};
73+
74+
# Instantiate a package set using the generated file.
75+
pkgSet = haskell.mkCabalProjectPkgSet {
76+
plan-pkgs = my-pkgs;
77+
pkg-def-extras = [];
78+
modules = [];
79+
};
80+
in
81+
pkgSet.config.hsPkgs
82+
```
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
Cross compilation of Haskell projects involves building a version of
2+
GHC that outputs code for the target platform, and providing builds of
3+
all library dependencies for that platform.
4+
5+
First, understand how to cross-compile a normal package from
6+
Nixpkgs. Matthew Bauer's [Beginners' guide to cross compilation in
7+
Nixpkgs][bauer] is a useful resource.
8+
9+
[bauer]: https://matthewbauer.us/blog/beginners-guide-to-cross.html
10+
11+
12+
Using an example from the guide, this builds GNU Hello for a Raspberry
13+
Pi:
14+
15+
nix build -f '<nixpkgs>' pkgsCross.raspberryPi.hello
16+
17+
We will use the same principle in [Haskell.nix][] — replacing the normal
18+
package set `pkgs` with a cross-compiling package set
19+
`pkgsCross.raspberryPi`.
20+
21+
### Raspberry Pi example
22+
23+
This is an example of using [Haskell.nix][] to build the [Bench][]
24+
command-line utility.
25+
26+
```nix
27+
{ pkgs ? import <nixpkgs> {} }:
28+
let
29+
haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz);
30+
native = haskellNix { inherit pkgs; };
31+
in
32+
native.haskellPackages.bench.components.exes.bench
33+
```
34+
35+
Now switch the package set as in the previous example:
36+
37+
```nix
38+
{ pkgs ? import <nixpkgs> {} }:
39+
let
40+
haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz);
41+
raspberryPi = haskellNix { pkgs = pkgs.pkgsCross.raspberryPi; };
42+
in
43+
raspberryPi.haskellPackages.bench.components.exes.bench
44+
```
45+
46+
You should be prepared for a long wait because it first needs to build
47+
GHC, before building all the Haskell dependencies of [Bench][]. If all
48+
of these dependencies compiled successfully, I would be very surprised!
49+
50+
To fix the build problems, you must add extra configuration to the
51+
package set. Your project will have a [`mkStackPkgSet`](../reference/library.md#mkstackpkgset) or
52+
[`mkCabalProjectPkgSet`](../reference/library.md#mkcabalprojectpkgset). It is there where you must add module
53+
[options](options.md) for setting compiler flags and so on.
54+
55+
### Static executables with Musl libc
56+
57+
Another application of cross-compiling is to produce fully static
58+
binaries for Linux. For information about how to do that with the
59+
[Nixpkgs Haskell infrastructure][nixpkgs] (not [Haskell.nix][]), see
60+
[nh2/static‑haskell‑nix][nh2]. Vaibhav Sagar's linked [blog
61+
post][vaibhav] is also very informative.
62+
63+
64+
```nix
65+
{ pkgs ? import <nixpkgs> {} }:
66+
let
67+
haskellNix = import (builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz);
68+
musl64 = haskellNix { pkgs = pkgs.pkgsCross.musl64; };
69+
in
70+
musl64.haskellPackages.bench.components.exes.bench
71+
```
72+
73+
This example will build [Bench][] linked against Musl libc. However
74+
the executable will still be dynamically linked. To get fully static
75+
executables you must add package overrides to:
76+
77+
1. Disable dynamic linking
78+
2. Provide static versions of system libraries. (For more details, see
79+
[Vaibhav's article][vaibhav]).
80+
81+
```nix
82+
{
83+
packages.bench.components.exes.bench.configureFlags =
84+
stdenv.lib.optionals stdenv.hostPlatform.isMusl [
85+
"--disable-executable-dynamic"
86+
"--disable-shared"
87+
"--ghc-option=-optl=-pthread"
88+
"--ghc-option=-optl=-static"
89+
"--ghc-option=-optl=-L${gmp6.override { withStatic = true; }}/lib"
90+
"--ghc-option=-optl=-L${zlib.static}/lib"
91+
];
92+
}
93+
```
94+
95+
!!! note "Licensing"
96+
Note that if copyleft licensing your program is a problem for you,
97+
then you need to statically link with `integer-simple` rather than
98+
`integer-gmp`. However, at present, [Haskell.nix][] does not provide
99+
an option for this.
100+
101+
[nh2]: https://github.com/nh2/static-haskell-nix
102+
[vaibhav]: https://vaibhavsagar.com/blog/2018/01/03/static-haskell-nix/
103+
[haskell.nix]: https://github.com/input-output-hk/haskell.nix
104+
[bench]: https://hackage.haskell.org/package/bench
105+
[nixpkgs]: https://nixos.org/nixpkgs/manual/#users-guide-to-the-haskell-infrastructure

0 commit comments

Comments
 (0)