From 37df73d3d8314e6b96cb1ccb7cd91ed796bdfa3a Mon Sep 17 00:00:00 2001 From: Lin Jian Date: Sun, 28 Jul 2024 12:27:52 +0800 Subject: [PATCH] emacs: teach elisp builders the finalAttrs pattern This commit causes 0 rebuilds. The performance overhead of eval time is as follows: | package set | before | after | changed | |--------------------------|--------|-------|---------| | emacs.pkgs.elpaPackages | 1.925 | 1.935 | +0.35% | | emacs.pkgs.melpaPackages | 8.312 | 8.558 | +3.0% | The commands used here are nix nixpkgs#hyperfine -- --warmup 2 --runs 10 'NIXPKGS_ALLOW_BROKEN=1 nix eval --include nixpkgs=$PWD --file . emacs.pkgs.melpaPackages --apply \'pkgSet: map (drv: drv.drvPath) (builtins.filter (p: p.type or null == "derivation") (builtins.attrValues pkgSet))\' --no-eval-cache >/dev/null' nix nixpkgs#hyperfine -- --warmup 10 --runs 30 'NIXPKGS_ALLOW_BROKEN=1 nix eval --include nixpkgs=$PWD --file . emacs.pkgs.elpaPackages --apply \'pkgSet: map (drv: drv.drvPath) (builtins.filter (p: p.type or null == "derivation") (builtins.attrValues pkgSet))\' --no-eval-cache >/dev/null' --- .../editors/emacs/build-support/elpa.nix | 13 +++-- .../editors/emacs/build-support/generic.nix | 8 ++- .../emacs/build-support/lib-build-helper.nix | 56 +++++++++++++++++++ .../editors/emacs/build-support/melpa.nix | 32 ++++++----- .../editors/emacs/build-support/trivial.nix | 20 +++++-- 5 files changed, 103 insertions(+), 26 deletions(-) create mode 100644 pkgs/applications/editors/emacs/build-support/lib-build-helper.nix diff --git a/pkgs/applications/editors/emacs/build-support/elpa.nix b/pkgs/applications/editors/emacs/build-support/elpa.nix index 7ac8d673346a..c87457ff16d9 100644 --- a/pkgs/applications/editors/emacs/build-support/elpa.nix +++ b/pkgs/applications/editors/emacs/build-support/elpa.nix @@ -3,23 +3,26 @@ { lib, stdenv, emacs, texinfo, writeText }: let - handledArgs = [ "meta" ]; genericBuild = import ./generic.nix { inherit lib stdenv emacs texinfo writeText; }; + libBuildHelper = import ./lib-build-helper.nix { inherit lib; }; in +libBuildHelper.extendMkDerivation { } genericBuild (finalAttrs: + { pname , version , src +, dontUnpack ? true , meta ? {} , ... }@args: -genericBuild ({ +{ - dontUnpack = true; + inherit dontUnpack; - installPhase = '' + installPhase = args.installPhase or '' runHook preInstall emacs --batch -Q -l ${./elpa2nix.el} \ @@ -34,4 +37,4 @@ genericBuild ({ } // meta; } -// removeAttrs args handledArgs) +) diff --git a/pkgs/applications/editors/emacs/build-support/generic.nix b/pkgs/applications/editors/emacs/build-support/generic.nix index d529d3cf09f9..914387979fc2 100644 --- a/pkgs/applications/editors/emacs/build-support/generic.nix +++ b/pkgs/applications/editors/emacs/build-support/generic.nix @@ -21,8 +21,12 @@ let fi ''; + libBuildHelper = import ./lib-build-helper.nix { inherit lib; }; + in +libBuildHelper.adaptMkDerivation { } stdenv.mkDerivation (finalAttrs: + { pname , version , buildInputs ? [] @@ -37,7 +41,7 @@ in , ... }@args: -stdenv.mkDerivation (finalAttrs: ({ +{ name = "emacs-${finalAttrs.pname}-${finalAttrs.version}"; unpackCmd = '' @@ -96,4 +100,4 @@ stdenv.mkDerivation (finalAttrs: ({ '' + postInstall; } -// removeAttrs args handledArgs)) +// removeAttrs args handledArgs) diff --git a/pkgs/applications/editors/emacs/build-support/lib-build-helper.nix b/pkgs/applications/editors/emacs/build-support/lib-build-helper.nix new file mode 100644 index 000000000000..7ae7003c9352 --- /dev/null +++ b/pkgs/applications/editors/emacs/build-support/lib-build-helper.nix @@ -0,0 +1,56 @@ +# stolen from https://github.com/NixOS/nixpkgs/pull/234651 +# TODO switch to functions in that PR once it is merged + +{ lib }: + +let + inherit (lib) + setFunctionArgs + id + functionArgs + optionalAttrs + toFunction + ; +in +{ + + extendMkDerivation = + { + modify ? id, + inheritFunctionArgs ? true, + }: + mkDerivationBase: attrsOverlay: + setFunctionArgs + # Adds the fixed-point style support. + (fpargs: modify ((mkDerivationBase fpargs).overrideAttrs attrsOverlay)) + # Add __functionArgs + ( + # Inherit the __functionArgs from the base build helper + functionArgs (attrsOverlay { }) + # Recover the __functionArgs from the derived build helper + // optionalAttrs inheritFunctionArgs (functionArgs mkDerivationBase) + ) + // { + # Passthru attributes attached to the result build helper. + attrsOverlays = mkDerivationBase.attrsOverlays or [ ] ++ [ attrsOverlay ]; + }; + + adaptMkDerivation = + { + modify ? id, + inheritFunctionArgs ? true, + }: + mkDerivationBase: adaptArgs: + setFunctionArgs + # Adds the fixed-point style support + ( + fpargs: modify (mkDerivationBase (finalAttrs: adaptArgs finalAttrs (toFunction fpargs finalAttrs))) + ) + # Add __functionArgs + ( + # Inherit the __functionArgs from the base build helper + optionalAttrs inheritFunctionArgs (functionArgs mkDerivationBase) + # Recover the __functionArgs from the derived build helper + // functionArgs (adaptArgs { }) + ); +} diff --git a/pkgs/applications/editors/emacs/build-support/melpa.nix b/pkgs/applications/editors/emacs/build-support/melpa.nix index 20f7e79eb683..c5adaac76548 100644 --- a/pkgs/applications/editors/emacs/build-support/melpa.nix +++ b/pkgs/applications/editors/emacs/build-support/melpa.nix @@ -4,8 +4,8 @@ { lib, stdenv, fetchFromGitHub, emacs, texinfo, writeText }: let - handledArgs = [ "meta" "preUnpack" "postUnpack" ]; genericBuild = import ./generic.nix { inherit lib stdenv emacs texinfo writeText; }; + libBuildHelper = import ./lib-build-helper.nix { inherit lib; }; packageBuild = stdenv.mkDerivation { name = "package-build"; @@ -29,6 +29,8 @@ let in +libBuildHelper.extendMkDerivation { } genericBuild (finalAttrs: + { /* pname: Nix package name without special symbols and without version or "emacs-" prefix. @@ -51,7 +53,7 @@ in This will be written into the generated package but it is not needed during the build process. */ -, commit ? (args.src.rev or "unknown") +, commit ? (finalAttrs.src.rev or "unknown") /* files: Optional recipe property specifying the files used to build the package. If null, do not set it in recipe, keeping the default upstream behaviour. @@ -62,9 +64,9 @@ in recipe: Optional MELPA recipe. Default: a minimally functional recipe */ -, recipe ? (writeText "${pname}-recipe" '' - (${ename} :fetcher git :url "" - ${lib.optionalString (files != null) ":files ${files}"}) +, recipe ? (writeText "${finalAttrs.pname}-recipe" '' + (${finalAttrs.ename} :fetcher git :url "" + ${lib.optionalString (finalAttrs.files or null != null) ":files ${finalAttrs.files}"}) '') , preUnpack ? "" , postUnpack ? "" @@ -72,14 +74,16 @@ in , ... }@args: -genericBuild ({ +{ - elpa2nix = ./elpa2nix.el; - melpa2nix = ./melpa2nix.el; + elpa2nix = args.elpa2nix or ./elpa2nix.el; + melpa2nix = args.melpa2nix or ./melpa2nix.el; - inherit packageBuild commit ename recipe; + inherit commit ename recipe; - melpaVersion = + packageBuild = args.packageBuild or packageBuild; + + melpaVersion = args.melpaVersion or ( let parsed = lib.flip builtins.match version # match -unstable-YYYY-MM-DD format @@ -90,7 +94,7 @@ genericBuild ({ in if unstableVersionInNixFormat then date + "." + time - else version; + else finalAttrs.version); preUnpack = '' mkdir -p "$NIX_BUILD_TOP/recipes" @@ -108,7 +112,7 @@ genericBuild ({ ln -s "$NIX_BUILD_TOP/$sourceRoot" "$NIX_BUILD_TOP/working/$ename" '' + postUnpack; - buildPhase = '' + buildPhase = args.buildPhase or '' runHook preBuild cd "$NIX_BUILD_TOP" @@ -122,7 +126,7 @@ genericBuild ({ runHook postBuild ''; - installPhase = '' + installPhase = args.installPhase or '' runHook preInstall archive="$NIX_BUILD_TOP/packages/$ename-$melpaVersion.el" @@ -143,4 +147,4 @@ genericBuild ({ } // meta; } -// removeAttrs args handledArgs) +) diff --git a/pkgs/applications/editors/emacs/build-support/trivial.nix b/pkgs/applications/editors/emacs/build-support/trivial.nix index 522dec811865..71606d463a82 100644 --- a/pkgs/applications/editors/emacs/build-support/trivial.nix +++ b/pkgs/applications/editors/emacs/build-support/trivial.nix @@ -2,10 +2,20 @@ { callPackage, lib, ... }@envargs: -args: +let + libBuildHelper = import ./lib-build-helper.nix { inherit lib; }; +in -callPackage ./generic.nix envargs ({ - buildPhase = '' +libBuildHelper.extendMkDerivation { } (callPackage ./generic.nix envargs) (finalAttrs: + +{ pname +, version +, src +, ... +}@args: + +{ + buildPhase = args.buildPhase or '' runHook preBuild emacs -L . --batch -f batch-byte-compile *.el @@ -13,7 +23,7 @@ callPackage ./generic.nix envargs ({ runHook postBuild ''; - installPhase = '' + installPhase = args.installPhase or '' runHook preInstall LISPDIR=$out/share/emacs/site-lisp @@ -24,4 +34,4 @@ callPackage ./generic.nix envargs ({ ''; } -// args) +)