Hello, this is Edgar! We are open sourcing nix-ninja, an incremental build system for Nix that leverages dynamic derivations.
nix-ninja brings compilation unit level granularity to Nix builds. It targets ninja build files, a format for describing build graphs output by popular build systems like CMake and meson. This means that when you modify a single source file, only the affected compilation units need to be rebuilt, significantly reducing build times.
We’re excited because this gives Nix fine-grained caching with early cutoff optimisation (see the Build Systems à la Carte paper). Combined with remote build farms like Nixbuild.net, this moves Nix into the incremental cloud build systems arena, alongside Google’s Bazel and Meta’s Buck2.
Dynamic derivations and content-addressed derivations are still experimental features in Nix, so we’re hoping to accelerate their maturation by providing a compelling use-case and implementation. Our north star is to have Hydra (nixpkgs’ CI runner) support incremental compilation in nixpkgs for slow builds like LLVM.
nix-ninja can compile Nix itself today, but we’re still very early in its development. Given community interest in dynamic derivations and incremental compilation in Nix, we decided to open source it in an pre-alpha state to involve the community in its design.
Nice, I wonder if this could help making Android builds faster (IIRC doing emits a ninja build) as well? When I tried to play around with robotnix, that was the biggest barrier to iteration.
From the GitHub issues of n2 it seems like some Googlers are maintaining a ninja-fork for Android, but it’s unclear why a fork exists: GitHub · Where software is built
Would be great if we could get it working. Have people deployed nix stores to Android devices? I’m unfamiliar with the Android ecosystem.
Hm, at least some of the issues mention performance at Android’s scale, but no idea if that’s all the differences. It would probably be nice to have that for building, well, Android xD Especially since they say it’s an order of magnitude faster at their scale.
The thing I’m talking about here is robotnix — which is basically someone taking the whole Android build and stuffing it into a derivation. Of course it’s more complex than that, but ultimately building the OS happens inside a single derivation. If something fails at the end then you’ve just flushed a few hours of CPU time down the drain. It was especially vexing when I was trying to drag the existing PR updating GrapheneOS to Android 13 over the finish line (I gave up eventually, because my lack of familiarity with AOSP build process didn’t mesh well with long iteration times to learn how it ticks). If something like nix-ninja could be used to get incremental, cacheable builds out of that, it would be an awesome improvement to DX.
So no, that’s not really deploying a nix store onto an Android device, that all stays on the build host, you get a normal Android ROM at the end of that process. I know there are things like mobile-nixos and nix-on-droid which are more like that, but I haven’t really used them so can’t say much here (though I’d assume it’s probably somewhat orthogonal to granular builds?).
Wow, this is such a big deal. This is the missing piece for Nix, I’m convinced (and I was hoping dynamic derivations would actually lead to such an implementation eventually). Most exciting development in a long time.
If you wanted to try this, but didn’t feel like changing your nix globally, you can see if my PR works for you — I have used a slightly patched version of nix-portable to wrap a nix built from the correct commit and exposed that in the devshell, which seems to be enough to get things building.