diff options
Diffstat (limited to 'nix/buildLisp')
-rw-r--r-- | nix/buildLisp/README.md | 97 | ||||
-rw-r--r-- | nix/buildLisp/default.nix | 28 |
2 files changed, 107 insertions, 18 deletions
diff --git a/nix/buildLisp/README.md b/nix/buildLisp/README.md index 513656f5706d..8e45f3479c06 100644 --- a/nix/buildLisp/README.md +++ b/nix/buildLisp/README.md @@ -3,19 +3,94 @@ buildLisp.nix This is a build system for Common Lisp, written in Nix. -The project is in its early stages and currently supports nothing -other than compiling a bunch of Lisp sources into a combined FASL -file. +It aims to offer an alternative to ASDF for users who live in a +Nix-based ecosystem. This offers several advantages over ASDF: -This is what it currently looks like: +* 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: + +* There is no separate abstraction for tests at the moment (i.e. they + are built and run as programs) +* Only SBCL is supported (though the plan is to add support for at + least ABCL and Clozure CL, and maybe make it extensible) + +## 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 | + + 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 | + + 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. + +## Example + +Using buildLisp could look like this: ```nix -nix.buildLisp.library { - name = "test-lib"; - srcs = [ - ./nix/buildLisp/test-lib.lisp - ]; +{ 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 ]; } ``` - -Check back here in a few days for more information. diff --git a/nix/buildLisp/default.nix b/nix/buildLisp/default.nix index 66de38663108..3203206fbe7e 100644 --- a/nix/buildLisp/default.nix +++ b/nix/buildLisp/default.nix @@ -8,7 +8,7 @@ , ... }: let - inherit (builtins) map elemAt match; + inherit (builtins) map elemAt match filter; inherit (pkgs.third_party) lib runCommandNoCC makeWrapper writeText writeShellScriptBin sbcl; # @@ -116,6 +116,7 @@ let lispDeps = allDeps deps; in runCommandNoCC "${name}-cllib" { LD_LIBRARY_PATH = lib.makeLibraryPath lispNativeDeps; + LANG = "C.UTF-8"; } '' ${sbcl}/bin/sbcl --script ${genCompileLisp srcs lispDeps} @@ -130,6 +131,7 @@ let '' // { inherit lispNativeDeps lispDeps; lispName = name; + lispBinary = false; }; # 'program' creates an executable containing a dumped image of the @@ -153,19 +155,31 @@ let } wrapProgram $out/bin/${name} --prefix LD_LIBRARY_PATH : "${libPath}" - ''; + '' // { + lispName = name; + lispDeps = [ selfLib ]; + lispNativeDeps = native; + lispBinary = true; + }; + + # 'bundled' creates a "library" that calls 'require' on a built-in + # package, such as any of SBCL's sb-* packages. + bundled = name: (makeOverridable library) { + inherit name; + srcs = lib.singleton (builtins.toFile "${name}.lisp" "(require '${name})"); + }; # 'sbclWith' creates an image with the specified libraries / # programs loaded. - sbclWith = deps: let lispDeps = allDeps deps; in writeShellScriptBin "sbcl" '' + sbclWith = deps: + let lispDeps = filter (d: !d.lispBinary) (allDeps deps); + in writeShellScriptBin "sbcl" '' export LD_LIBRARY_PATH=${lib.makeLibraryPath (allNative [] lispDeps)}; - exec ${sbcl}/bin/sbcl ${ - if deps == [] then "" - else "--load ${writeText "load.lisp" (genLoadLisp lispDeps)}" - } $@ + exec ${sbcl}/bin/sbcl ${lib.optionalString (deps != []) "--load ${writeText "load.lisp" (genLoadLisp lispDeps)}"} $@ ''; in { library = makeOverridable library; program = makeOverridable program; sbclWith = makeOverridable sbclWith; + bundled = makeOverridable bundled; } |