{ pkgs }: rec { /* Prepare a derivation for local builds. * * This function prepares incremental builds by provinding, * containing the build output and the sources for cross checking. * The build output can be used later to allow incremental builds * by passing the derivation output to the `mkIncrementalBuild` function. * * To build a project incrementaly follow these steps: * - run prepareIncrementalBuild on the desired derivation * e.G `incrementalBuildArtifacts = (pkgs.buildIncremental.prepareIncrementalBuild pkgs.virtualbox);` * - change something you want in the sources of the package( e.G using source override) * changedVBox = pkgs.virtuabox.overrideAttrs (old: { * src = path/to/vbox/sources; * } * - use `mkIncrementalBuild changedVBox buildOutput` * - enjoy shorter build times */ prepareIncrementalBuild = drv: drv.overrideAttrs (old: { outputs = [ "out" ]; name = drv.name + "-incrementalBuildArtifacts"; preBuild = (old.preBuild or "") + '' mkdir -p $out/sources cp -r ./* $out/sources/ ''; installPhase = '' mkdir -p $out/outputs cp -r ./* $out/outputs/ ''; }); /* Build a derivation incrementally based on the output generated by * the `prepareIncrementalBuild function. * * Usage: * let * incrementalBuildArtifacts = prepareIncrementalBuild drv * in mkIncrementalBuild drv incrementalBuildArtifacts */ mkIncrementalBuild = drv: previousBuildArtifacts: drv.overrideAttrs (old: { preBuild = (old.preBuild or "") + '' set +e diff -ur ${previousBuildArtifacts}/sources ./ > sourceDifference.patch set -e shopt -s extglob rm -r !("sourceDifference.patch") ls -al . ${pkgs.rsync}/bin/rsync -cutU --chown=$USER:$USER --chmod=+w -r ${previousBuildArtifacts}/outputs/* . patch -p 1 -i sourceDifference.patch ''; }); }