about summary refs log tree commit diff
path: root/nix/buildLisp
diff options
context:
space:
mode:
authorsterni <sternenseemann@systemli.org>2021-08-15T12·30+0200
committersterni <sternenseemann@systemli.org>2021-08-24T22·00+0000
commit0285ea7eac8e214f6159c37ca1eff6ca61fc883b (patch)
tree465a369e96de83a8b1e2fdf15c5e2f68bd2c4cb3 /nix/buildLisp
parentee6b2003fc19337bcce49695a07fe477e221efe0 (diff)
feat(nix/buildLisp): expose drvs built w/ the other implementations r/2770
For every implementation we support an extra passthru attribute with the
name of the implementation is created which points to a version of the
derivation built with that implementation. E. g. if we support CCL, ECL
and SBCL, third_party.lisp.alexandria would have:

* third_party.lisp.alexandria.sbcl
* third_party.lisp.alexandria.ecl
* third_party.lisp.alexandria.ccl

To make this possible, the REPL derivation which was called `sbcl`
originally has been renamed to `repl`.

Since some things won't build with all implementations, we introduce a
brokenOn argument which influences the meta.targets list that is
created, but won't prevent the passthru attrs from being created to
ease debugging failures.

Change-Id: Icd6af345143593fac30ded10deabf31172e5d48a
Reviewed-on: https://cl.tvl.fyi/c/depot/+/3359
Tested-by: BuildkiteCI
Reviewed-by: tazjin <mail@tazj.in>
Diffstat (limited to 'nix/buildLisp')
-rw-r--r--nix/buildLisp/default.nix58
1 files changed, 48 insertions, 10 deletions
diff --git a/nix/buildLisp/default.nix b/nix/buildLisp/default.nix
index 84d5ef08c9..c214a542de 100644
--- a/nix/buildLisp/default.nix
+++ b/nix/buildLisp/default.nix
@@ -90,10 +90,12 @@ let
   # all use the given implementation.
   allDeps = impl: deps: let
     # The override _should_ propagate itself recursively, as every derivation
-    # would only expose its actually used dependencies
-    deps' = builtins.map (dep: dep.overrideLisp or (lib.const dep) (_: {
+    # would only expose its actually used dependencies. Use implementation
+    # attribute created by withExtras if present, override in all other cases
+    # (mainly bundled).
+    deps' = builtins.map (dep: dep."${impl.name}" or (dep.overrideLisp (_: {
       implementation = impl.name;
-    })) deps;
+    }))) deps;
   in (lib.toposort dependsOn (lib.unique (
     lib.flatten (deps' ++ (map (d: d.lispDeps) deps'))
   ))).result;
@@ -112,6 +114,40 @@ let
     overrideLisp = new: makeOverridable f (orig // (new orig));
   };
 
+  # This is a wrapper arround 'makeOverridable' which performs its
+  # function, but also adds a the following additional attributes to the
+  # resulting derivation, namely a repl attribute which builds a `lispWith`
+  # derivation for the current implementation and additional attributes for
+  # every all implementations. So `drv.sbcl` would build the derivation
+  # with SBCL regardless of what was specified in the initial arguments.
+  withExtras = f: args:
+    let
+      drv = (makeOverridable f) args;
+    in lib.fix (self:
+      drv.overrideLisp (old:
+        let
+          implementation = old.implementation or defaultImplementation;
+          brokenOn = old.brokenOn or [];
+          targets = lib.subtractLists brokenOn
+            (builtins.attrNames impls);
+        in {
+          passthru = (old.passthru or {}) // {
+            repl = impls."${implementation}".lispWith [ self ];
+
+            # meta is done via passthru to minimize rebuilds caused by overriding
+            meta = (old.passthru.meta or {}) // {
+              inherit targets;
+            };
+          } // builtins.listToAttrs (builtins.map (name: {
+            inherit name;
+            value = self.overrideLisp (_: {
+              implementation = name;
+            });
+          }) (builtins.attrNames impls));
+        }) // {
+          overrideLisp = new: withExtras f (args // new args);
+        });
+
   # 'testSuite' builds a Common Lisp test suite that loads all of srcs and deps,
   # and then executes expression to check its result
   testSuite = { name, expression, srcs, deps ? [], native ? [], impl }:
@@ -280,10 +316,12 @@ let
   library =
     { name
     , implementation ? defaultImplementation
+    , brokenOn ? [] # TODO(sterni): make this a warning
     , srcs
     , deps ? []
     , native ? []
     , tests ? null
+    , passthru ? {}
     }:
     let
       impl = impls."${implementation}" or
@@ -304,12 +342,11 @@ let
     in lib.fix (self: runCommandNoCC "${name}-cllib" {
       LD_LIBRARY_PATH = lib.makeLibraryPath lispNativeDeps;
       LANG = "C.UTF-8";
-      passthru = {
+      passthru = passthru // {
         inherit lispNativeDeps lispDeps;
         lispName = name;
         lispBinary = false;
         tests = testDrv;
-        ${implementation} = impl.lispWith [ self ];
       };
     } ''
       ${if ! isNull testDrv
@@ -332,11 +369,13 @@ let
   program =
     { name
     , implementation ? defaultImplementation
+    , brokenOn ? [] # TODO(sterni): make this a warning
     , main ? "${name}:main"
     , srcs
     , deps ? []
     , native ? []
     , tests ? null
+    , passthru ? {}
     }:
     let
       impl = impls."${implementation}" or
@@ -347,7 +386,7 @@ let
       libPath = lib.makeLibraryPath (allNative native lispDeps);
       # overriding is used internally to propagate the implementation to use
       selfLib = (makeOverridable library) {
-        inherit name native;
+        inherit name native brokenOn;
         deps = lispDeps;
         srcs = filteredSrcs;
       };
@@ -366,13 +405,12 @@ let
       nativeBuildInputs = [ makeWrapper ];
       LD_LIBRARY_PATH = libPath;
       LANG = "C.UTF-8";
-      passthru = {
+      passthru = passthru // {
         lispName = name;
         lispDeps = [ selfLib ];
         lispNativeDeps = native;
         lispBinary = true;
         tests = testDrv;
-        ${implementation} = impl.lispWith [ self ];
       };
     } ''
       ${if ! isNull testDrv
@@ -413,8 +451,8 @@ let
     };
 
 in {
-  library = makeOverridable library;
-  program = makeOverridable program;
+  library = withExtras library;
+  program = withExtras program;
   inherit bundled;
 
   # 'sbclWith' creates an image with the specified libraries /