feat(nix/buildLisp): expose drvs built w/ the other implementations

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>
This commit is contained in:
sterni 2021-08-15 14:30:18 +02:00
parent ee6b2003fc
commit 0285ea7eac

View file

@ -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 /