From dae0dca5d1c9ad4150b91c55c5f4b54430b1413c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kasper=20Ga=C5=82kowski?= Date: Sat, 11 Mar 2023 18:53:26 +0100 Subject: [PATCH] lisp-modules: second version of wrapLisp The previous approach of trying to make both the `override` mechanism from `mkDerivation` and the `overrideScope'` mechanism from `newScope` work together resulted in hard to understand code, and there was a bug where once overridden packages would lose the changes on next override with `packageOverrides`. It's not ideal still, because Lisps created by `mkDerivation` will lose their `pkgs` after using `override`. --- doc/languages-frameworks/lisp.section.md | 65 +++++++++++------------- pkgs/development/lisp-modules/nix-cl.nix | 29 ++++++----- 2 files changed, 44 insertions(+), 50 deletions(-) diff --git a/doc/languages-frameworks/lisp.section.md b/doc/languages-frameworks/lisp.section.md index d39a812d14a1..2873a2eb573f 100644 --- a/doc/languages-frameworks/lisp.section.md +++ b/doc/languages-frameworks/lisp.section.md @@ -27,11 +27,11 @@ FASLs available to wrappers. Any other use-cases, such as producing SBCL executables with `sb-ext:save-lisp-and-die`, are achieved via overriding the `buildPhase` etc. -In addition, Lisps have the `packageOverrides` argument, which can be used -(through `override`) to substitute any package in the scope of their -`pkgs`. This will be useful together with `overrideLispAttrs` when dealing with -slashy ASDF systems, because they should stay in the main package and be build -by specifying the `systems` argument to `build-asdf-system`. +In addition, Lisps have the `withOverrides` function, which can be used to +substitute any package in the scope of their `pkgs`. This will be useful +together with `overrideLispAttrs` when dealing with slashy ASDF systems, because +they should stay in the main package and be build by specifying the `systems` +argument to `build-asdf-system`. ## The 90% use case example @@ -152,8 +152,7 @@ function, which is the same as `build-asdf-system`, except for the `lisp` argument which is set to the given CL implementation. It can be used to define packages outside Nixpkgs, and, for example, add them -into the package scope with `override` and `packageOverrides`, both of which -will be discussed later on. +into the package scope with `withOverrides` which will be discussed later on. ### Including an external package in scope @@ -173,11 +172,9 @@ let hash = "sha256-1Hzxt65dZvgOFIljjjlSGgKYkj+YBLwJCACi5DZsKmQ="; }; }; - sbcl' = sbcl.override { - packageOverrides = self: super: { - inherit alexandria; - }; - }; + sbcl' = sbcl.withOverrides (self: super: { + inherit alexandria; + }); in sbcl'.pkgs.alexandria ``` @@ -203,26 +200,23 @@ sbcl.pkgs.alexandria.overrideLispAttrs (oldAttrs: rec { ## Overriding packages in scope -Packages can be woven into a new scope by using `override` with -`packageOverrides`: +Packages can be woven into a new scope by using `withOverrides`: ``` let - sbcl' = sbcl.override { - packageOverrides = self: super: { - alexandria = super.alexandria.overrideLispAttrs (oldAttrs: rec { - pname = "alexandria"; - version = "1.4"; - src = fetchFromGitLab { - domain = "gitlab.common-lisp.net"; - owner = "alexandria"; - repo = "alexandria"; - rev = "v${version}"; - hash = "sha256-1Hzxt65dZvgOFIljjjlSGgKYkj+YBLwJCACi5DZsKmQ="; - }; - }); - }; - }; + sbcl' = sbcl.withOverrides (self: super: { + alexandria = super.alexandria.overrideLispAttrs (oldAttrs: rec { + pname = "alexandria"; + version = "1.4"; + src = fetchFromGitLab { + domain = "gitlab.common-lisp.net"; + owner = "alexandria"; + repo = "alexandria"; + rev = "v${version}"; + hash = "sha256-1Hzxt65dZvgOFIljjjlSGgKYkj+YBLwJCACi5DZsKmQ="; + }; + }); + }); in builtins.elemAt sbcl'.pkgs.bordeaux-threads.lispLibs 0 ``` @@ -246,7 +240,8 @@ ecl.pkgs.alexandria.overrideLispAttrs (oldAttrs: { }) ``` -See the respective section for how to weave it back into `ecl.pkgs`. +See the respective section on using `withOverrides` for how to weave it back +into `ecl.pkgs`. Note that sometimes the slashy systems might not only have more dependencies than the main one, but create a circular dependency between `.asd` @@ -285,12 +280,9 @@ loaded. ## Adding a new Lisp -The function `wrapLisp` is used to wrap Common Lisp implementations and does this: - -- Adds the `pkgs` attribute -- Adds the `withPackages` attribute -- Adds the `buildASDFSystem` attribute -- Modifies `override` to take an additional `packageOverrides` argument +The function `wrapLisp` is used to wrap Common Lisp implementations. It adds the +`pkgs`, `withPackages`, `withOverrides` and `buildASDFSystem` attributes to the +derivation. `wrapLisp` takes these arguments: @@ -299,6 +291,7 @@ The function `wrapLisp` is used to wrap Common Lisp implementations and does thi - `program`: The name of executable file in `${pkg}/bin/` (Default: `pkg.pname`) - `flags`: A list of flags to always pass to `program` (Default: `[]`) - `asdf`: The ASDF version to use (Default: `pkgs.asdf_3_3`) +- `packageOverrides`: Package overrides config (Default: `(self: super: {})`) This example wraps CLISP: diff --git a/pkgs/development/lisp-modules/nix-cl.nix b/pkgs/development/lisp-modules/nix-cl.nix index 7e671e7cc637..d1a70bf5c8e3 100644 --- a/pkgs/development/lisp-modules/nix-cl.nix +++ b/pkgs/development/lisp-modules/nix-cl.nix @@ -286,25 +286,26 @@ let ''; }); - wrapLisp = { pkg, faslExt, program ? pkg.pname, flags ? [], asdf ? pkgs.asdf_3_3 }: + wrapLisp = { + pkg + , faslExt + , program ? pkg.pname + , flags ? [] + , asdf ? pkgs.asdf_3_3 + , packageOverrides ? (self: super: {}) + }: let spec = { inherit pkg faslExt program flags asdf; }; - pkgs = commonLispPackagesFor spec; + pkgs = (commonLispPackagesFor spec).overrideScope' packageOverrides; withPackages = lispWithPackages pkgs; - override = - { packageOverrides ? (self: super: {}) , ... } @ attrs: - let - pkg' = spec.pkg.override attrs; - spec' = spec // { pkg = pkg'; }; - pkgs = (commonLispPackagesFor spec').overrideScope' packageOverrides; - withPackages = lispWithPackages pkgs; - in pkg' // { - inherit pkgs withPackages override; - buildASDFSystem = args: build-asdf-system (args // spec'); + withOverrides = packageOverrides: + wrapLisp { + inherit pkg faslExt program flags asdf; + inherit packageOverrides; }; - in pkg // { - inherit pkgs withPackages override; buildASDFSystem = args: build-asdf-system (args // spec); + in pkg // { + inherit pkgs withPackages withOverrides buildASDFSystem; }; in wrapLisp