about summary refs log tree commit diff
path: root/pkgs/build-support
diff options
context:
space:
mode:
authorMartin Messer <martin.messer@cyberus-technology.de>2022-04-06 16:14:42 +0200
committerMartin Messer <martin.messer@cyberus-technology.de>2023-12-07 16:38:48 +0100
commit3f4e3a862f20370d36a59a9534788099225d3484 (patch)
treef7e1bb433f5d8b3dfc1a70d116c51c7f46195c8b /pkgs/build-support
parent2453c821f0a89bd579ac06f6a84152f41ee0c68b (diff)
Checkpointedbuilds: add derivation override functions
One can use this functions to allow incremental builds of derivations
Diffstat (limited to 'pkgs/build-support')
-rw-r--r--pkgs/build-support/build-incremental.nix37
1 files changed, 37 insertions, 0 deletions
diff --git a/pkgs/build-support/build-incremental.nix b/pkgs/build-support/build-incremental.nix
new file mode 100644
index 0000000000000..b2a4fd4617090
--- /dev/null
+++ b/pkgs/build-support/build-incremental.nix
@@ -0,0 +1,37 @@
+{ pkgs }:
+rec {
+  /* Prepare a derivation for local builds.
+    *
+    * This function adds an additional outout for a derivation,
+    * containing the build output.
+    * The build output can be used later to allow incremental builds
+    * by passing the `buildOut` output to the `mkIncrementalBuild` function.
+  */
+  prepareIncrementalBuild = drv: drv.overrideAttrs (old: {
+    outputs = (old.outputs or [ "out" ]) ++ [ "buildOut" ];
+    installPhase = pkgs.lib.optionalString (!(builtins.hasAttr "outputs" old)) ''
+      mkdir -p $out
+    '' + (old.installPhase or "") + ''
+      mkdir -p $buildOut
+      cp -r ./* $buildOut/
+    '';
+  });
+
+  /* Build a derivation incrementally based on the output generated by
+    * the `prepareIncrementalBuild function.
+    *
+    * Usage:
+    * let
+    *   buildOutput = (prepareIncrementalBuild drv).buildOut
+    * in mkIncrementalBuild drv buildOutput
+  */
+  mkIncrementalBuild = drv: previousBuildArtifacts: drv.overrideAttrs (old: {
+    prePatch = ''
+      for file in $(diff -r  ./ ${previousBuildArtifacts} --brief | grep  "Files" |sed 's/^Only in \([^:]*\): /\1\//' | sed 's/^Files \(.*\) and .* differ/\1/')
+      do
+        touch $file
+      done
+      ${pkgs.rsync}/bin/rsync -cutU --chown=$USER:$USER --chmod=+w -r ${previousBuildArtifacts}/* .
+    '' + (old.prePatch or "");
+  });
+}