about summary refs log tree commit diff
path: root/nix/buildLisp/README.md
blob: 5ee560e056694c398bbdbfce6966b89b01bda25f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
buildLisp.nix
=============

This is a build system for Common Lisp, written in Nix.

It aims to offer an alternative to ASDF for users who live in a
Nix-based ecosystem. This offers several advantages over ASDF:

* Simpler (logic-less) package definitions
* Easy linking of native dependencies (from Nix)
* Composability with Nix tooling for other languages
* Effective, per-system caching strategies
* Easy overriding of dependencies and whatnot
* ... and more!

The project is still in its early stages and some important
restrictions should be highlighted:

* Only SBCL is supported (though the plan is to add support for at
  least ABCL and Clozure CL, and maybe make it extensible)
* Parallel compilation is not possible: Since buildLisp doesn't encode
  dependencies between components (i. e. source files) like ASDF,
  it must compile source files in sequence to avoid errors due to
  undefined symbols.

## Usage

`buildLisp` exposes four different functions:

* `buildLisp.library`: Builds a collection of Lisp files into a library.

  | parameter | type         | use                           | required? |
  |-----------|--------------|-------------------------------|-----------|
  | `name`    | `string`     | Name of the library           | yes       |
  | `srcs`    | `list<path>` | List of paths to source files | yes       |
  | `deps`    | `list<drv>`  | List of dependencies          | no        |
  | `native`  | `list<drv>`  | List of native dependencies   | no        |
  | `test`    | see "Tests"  | Specification for test suite  | no        |

  The output of invoking this is a directory containing a FASL file
  that is the concatenated result of all compiled sources.

* `buildLisp.program`: Builds an executable program out of Lisp files.

  | parameter | type         | use                           | required? |
  |-----------|--------------|-------------------------------|-----------|
  | `name`    | `string`     | Name of the program           | yes       |
  | `srcs`    | `list<path>` | List of paths to source files | yes       |
  | `deps`    | `list<drv>`  | List of dependencies          | no        |
  | `native`  | `list<drv>`  | List of native dependencies   | no        |
  | `main`    | `string`     | Entrypoint function           | no        |
  | `test`    | see "Tests"  | Specification for test suite  | no        |

  The `main` parameter should be the name of a function and defaults
  to `${name}:main` (i.e. the *exported* `main` function of the
  package named after the program).

  The output of invoking this is a directory containing a
  `bin/${name}`.

* `buildLisp.bundled`: Creates a virtual dependency on a built-in library.

  Certain libraries ship with Lisp implementations, for example
  UIOP/ASDF are commonly included but many implementations also ship
  internals (such as SBCLs various `sb-*` libraries).

  This function takes a single string argument that is the name of a
  built-in library and returns a "package" that simply requires this
  library.

* `buildLisp.sbclWith`: Creates an SBCL pre-loaded with various dependencies.

  This function takes a single argument which is a list of Lisp
  libraries programs or programs. It creates an SBCL that is
  pre-loaded with all of that Lisp code and can be used as the host
  for e.g. Sly or SLIME.

## Tests

Both `buildLisp.library` and `buildLisp.program` take an optional argument
`tests`, which has the following supported fields:

  | parameter    | type         | use                           | required? |
  |--------------|--------------|-------------------------------|-----------|
  | `name`       | `string`     | Name of the test suite        | no        |
  | `expression` | `string`     | Lisp expression to run tests  | yes       |
  | `srcs`       | `list<path>` | List of paths to source files | no        |
  | `native`     | `list<drv>`  | List of native dependencies   | no        |

the `expression` parameter should be a Lisp expression and will be evaluated
after loading all sources and dependencies (including library/program
dependencies). It must return a non-`NIL` value if the test suite has passed.

## Example

Using buildLisp could look like this:

```nix
{ buildLisp, lispPkgs }:

let libExample = buildLisp.library {
    name = "lib-example";
    srcs = [ ./lib.lisp ];

    deps = with lispPkgs; [
      (buildLisp.bundled "sb-posix")
      iterate
      cl-ppcre
    ];
};
in buildLisp.program {
    name = "example";
    deps = [ libExample ];
    srcs = [ ./main.lisp ];
    tests = {
      deps = [ lispPkgs.fiveam ];
      srcs = [ ./tests.lisp ];
      expression = "(fiveam:run!)";
    };
}
```