docs(nix/buildLisp): document recent changes to buildLisp
Doing this in a separate CL to avoid having to track the intermediate changes no one will ever see in documentation as well which would be unnecessary effort. * Multi-implementation support introduced in cl/3292 and refined in cl/3368 in terms of the user interface. * Implementation specific srcs and deps introduced in cl/3321 * Implementation passthru attrs and rename from .sbcl -> .repl was done in cl/3359 * ECL added in cl/3297, CCL in cl/3350 Change-Id: Ia13f2aea4e7e091c00991fcbfc601de364413979 Reviewed-on: https://cl.tvl.fyi/c/depot/+/3380 Tested-by: BuildkiteCI Reviewed-by: tazjin <mail@tazj.in>
This commit is contained in:
		
							parent
							
								
									7df7cd6257
								
							
						
					
					
						commit
						2fa32b563f
					
				
					 1 changed files with 119 additions and 10 deletions
				
			
		|  | @ -6,18 +6,20 @@ 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 | ||||
| * Simpler (almost 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 | ||||
| * Convenient support for multiple Common Lisp implementations | ||||
| * ... 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) | ||||
| * Extending `buildLisp` with support for a custom implementation | ||||
|   currently requires some knowledge of internals and may not be | ||||
|   considered stable yet. | ||||
| * 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 | ||||
|  | @ -36,6 +38,7 @@ restrictions should be highlighted: | |||
|   | `deps`    | `list<drv>`  | List of dependencies          | no        | | ||||
|   | `native`  | `list<drv>`  | List of native dependencies   | no        | | ||||
|   | `test`    | see "Tests"  | Specification for test suite  | no        | | ||||
|   | `implementation` | see "Implementations" | Common Lisp implementation to use | no | | ||||
| 
 | ||||
|   The output of invoking this is a directory containing a FASL file | ||||
|   that is the concatenated result of all compiled sources. | ||||
|  | @ -50,6 +53,7 @@ restrictions should be highlighted: | |||
|   | `native`  | `list<drv>`  | List of native dependencies   | no        | | ||||
|   | `main`    | `string`     | Entrypoint function           | no        | | ||||
|   | `test`    | see "Tests"  | Specification for test suite  | no        | | ||||
|   | `implementation` | see "Implementations" | Common Lisp implementation to use | no | | ||||
| 
 | ||||
|   The `main` parameter should be the name of a function and defaults | ||||
|   to `${name}:main` (i.e. the *exported* `main` function of the | ||||
|  | @ -68,13 +72,6 @@ restrictions should be highlighted: | |||
|   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 | ||||
|  | @ -91,6 +88,113 @@ 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. | ||||
| 
 | ||||
| ## Development REPLs | ||||
| 
 | ||||
| `buildLisp` builds loadable variants of both `program` and `library` derivations | ||||
| (usually FASL files). Therefore it can provide a convenient way to obtain an | ||||
| instance of any implementation preloaded with `buildLisp`-derivations. This | ||||
| is especially useful to use as a host for Sly or SLIME. | ||||
| 
 | ||||
| * `buildLisp.sbcl.lispWith`, `buildLisp.ccl.lispWith`, ...: | ||||
|   Creates a wrapper script preloading a Lisp implementation with various dependencies. | ||||
| 
 | ||||
|   This function takes a single argument which is a list of Lisp | ||||
|   libraries programs or programs. The desired Lisp implementation | ||||
|   will load all given derivations and all their dependencies on | ||||
|   startup. | ||||
| 
 | ||||
|   The shortcut `buildLisp.sbclWith` for `buildLisp.sbcl.lispWith` is also provided. | ||||
| 
 | ||||
| * `repl` passthru attribute: `derivation.repl` is provided as a shortcut | ||||
|   for `buildLisp.${implementationName}.lispWith [ derivation ]`. | ||||
|   `derivation.ccl.repl`, `derivation.sbcl.repl` etc. work as well, of course | ||||
|   (see also "Implementations" section). | ||||
| 
 | ||||
| ## Implementations | ||||
| 
 | ||||
| Both `buildLisp.library` and `buildLisp.program` allow specifying a different | ||||
| Common Lisp implementation than the default one (which is SBCL). When an | ||||
| implementation is passed, `buildLisp` makes sure all dependencies are built | ||||
| with that implementation as well since build artifacts from different | ||||
| implementation will be incompatible with each other. | ||||
| 
 | ||||
| The argument taken by `implementation` is a special attribute set which | ||||
| describes how to do certain tasks for a given implementation, like building | ||||
| or loading a library. In case you want to use a custom implementation | ||||
| description, the precise structure needed is documented in `buildLisp`'s | ||||
| source code for now. `buildLisp` also exposes the following already | ||||
| working implementation sets: | ||||
| 
 | ||||
| * `buildLisp.sbcl`: [SBCL][sbcl], our default implementation | ||||
| 
 | ||||
| * `buildLisp.ccl`: [CCL][ccl], similar to SBCL, but with very good macOS support | ||||
| 
 | ||||
| * `buildLisp.ecl`: [ECL][ecl] setup to produce statically linked binaries and | ||||
|   libraries. Note that its runtime library is LGPL, so [extra conditions][lgpl-static] | ||||
|   must be fulfilled when distributing binaries produced this way. | ||||
| 
 | ||||
| * Support for ABCL is planned. | ||||
| 
 | ||||
| For every of these “known” implementations, `buildLisp` will create a `passthru` | ||||
| attribute named like the implementation which points to a variant of the derivation | ||||
| built with said implementation. Say we have a derivation, `myDrv`, built using SBCL: | ||||
| While `myDrv` and `myDrv.sbcl` are built using SBCL, `myDrv.ecl`, `myDrv.ccl` etc. | ||||
| build the derivation and all its dependencies using ECL and CCL respectively. | ||||
| 
 | ||||
| This is useful to test portability of your derivation, but is also used internally | ||||
| to speed up the “normalization” of the dependency graph. Thus it is important to | ||||
| make sure that your custom implementation's name doesn't clash with one of the | ||||
| “known” ones. | ||||
| 
 | ||||
| ## Handling Implementation Specifics | ||||
| 
 | ||||
| When targeting multiple Common Lisp implementation, it is often necessary to | ||||
| handle differing interfaces for OS interaction or to make use of special | ||||
| implementation features. For this reason, `buildLisp` allows specifying | ||||
| dependencies and source files for specific implementations only. This can | ||||
| be utilized by having an attribute set in the list for the `deps` or `srcs` | ||||
| argument: `buildLisp` will pick the value of the attribute named like the | ||||
| used implementation or `default` and ignore the set completely if both | ||||
| are missing. | ||||
| 
 | ||||
| ```nix | ||||
| { buildLisp, lispPkgs }: | ||||
| 
 | ||||
| buildLisp.library { | ||||
|   name = "mylib"; | ||||
| 
 | ||||
|   srcs = [ | ||||
|     # These are included always of course | ||||
|     ./package.lisp | ||||
|     ./portable-lib.lisp | ||||
| 
 | ||||
|     # Choose right impl-* file | ||||
|     { | ||||
|       sbcl = ./impl-sbcl.lisp; | ||||
|       ccl = ./impl-ccl.lisp; | ||||
|       ecl = ./impl-ecl.lisp; | ||||
|     } | ||||
| 
 | ||||
|     # We can also use this to inject extra files | ||||
|     { ecl = ./extra-ecl-optimizations.lisp; } | ||||
|   ]; | ||||
| 
 | ||||
|   deps = [ | ||||
|     # Use SBCL's special bundled package, flexi-streams otherwise | ||||
|     { | ||||
|       sbcl = buildLisp.bundled "sb-rotate-byte"; | ||||
|       default = lispPkgs.flexi-streams; | ||||
|     } | ||||
|   ]; | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| Additionally a `brokenOn` parameter is accepted which takes a list of | ||||
| implementation names on which the derivation is not expected to work. | ||||
| This only influences `meta.targets` which is read by depot's CI to | ||||
| check which variants (see "Implementations") of the derivation to | ||||
| build, so it may not be useful outside of depot. | ||||
| 
 | ||||
| ## Example | ||||
| 
 | ||||
| Using buildLisp could look like this: | ||||
|  | @ -119,3 +223,8 @@ in buildLisp.program { | |||
|     }; | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| [sbcl]: http://www.sbcl.org/ | ||||
| [ccl]: https://ccl.clozure.com/ | ||||
| [ecl]: https://common-lisp.net/project/ecl/ | ||||
| [lgpl-static]: https://www.gnu.org/licenses/gpl-faq.en.html#LGPLStaticVsDynamic | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue