From 0285ea7eac8e214f6159c37ca1eff6ca61fc883b Mon Sep 17 00:00:00 2001 From: sterni Date: Sun, 15 Aug 2021 14:30:18 +0200 Subject: 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 --- nix/buildLisp/default.nix | 58 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 10 deletions(-) (limited to 'nix/buildLisp') 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 / -- cgit 1.4.1