This is a naive idea: can we automatically generate an intermediate, unwrapped package right after package build (before postBuild
)? This could potentially be realized in the mkDerivation
internals without any user facing API changes.
Rationale: Since the actual package build is usually the most resource intensive / time-consuming part of writing / tweaking / overriding a package, it would be quite nice to reuse the build results as long as everything before preBuild
has not changed.
Also, in nixpkgs there are a lot of unwrapped
packages + wrappers constructed with symlinkJoin
and the likes, precisely to avoid this problem of rebuilding the binaries. That’s a lot of boilerplate! Many of them can be simplified if things after postBuild
are low-cost operations: one can just .overrideAttrs
without rebuilding the whole package.
Implementations: I have no idea about the mkDerivation
internals, so this is just a sketch of a possible way of implementing this idea:
- When
mkDerivation
is called on somepackage
, generate apackage-vanilla
derivation with everything after (and including)postBuild
stripped, and generate the usualpackage
derivation by wrappingpackage-vanilla
. - When building the package,
package-vanilla
is first built, copied into a new store for the eventualpackage
(do not symlink to avoid possible issues), and thepostBuild
commands are applied to generate the finalpackage
. - This new behavior can be protected behind a
mkDerivation
flag such asvanillaPackage = true;
What do you think? Again, I am relatively new to nix, and this might be an unrealistic idea; if this is the case, please let me know!
Update: as pointed out by @shamrocklee something similar is introduced very recently:
https://github.com/NixOS/nixpkgs/pull/167670
Documentation: https://github.com/NixOS/nixpkgs/blob/master/doc/build-helpers/special/checkpoint-build.section.md