Nix-on-Droid: gnumake 4.3 broke, how do I graft stdenv? what else can I do?

Hello. I have a problem.
My current formulation of it is “how do I replace gnumake in stdenv without rebuilding the world”, but I’m not sure I’m heading into the right direction with this, so I’d like to hear other takes on my problem.

I’m preparing to release Nix-on-Droid 20.09. It’s an odd way to ship Nix where it’s running inside PRoot that’s cross-compiled for Android, but doesn’t use bionic. And something somewhere inside this contraption breaks gnumake 4.3 that’s currently in nixpkgs 20.09. It cannot spawn any process, spewing: Function not implemented. On one of the devices I own, that is, one other is perfectly fine.

Of course, the real solution is to fix whatever goes wrong inside that make/glibc/proot/bionic/old kernel sandwich. I’ve tried, but I’m seriously underqualifed for that. So I’m currently exploring Nix-side solutions to the problem.

I can build things with gnumake42. I can thus build gnumake without the offending change in question:

self: super: { working-gnumake = super.gnumake.overrideAttrs (old: {
  buildPhase = "${super.gnumake42}/bin/make";
  installPhase = ''
    mkdir -p $out
    ${super.gnumake42}/bin/make install
  '';

  configureFlags = old.configureFlags ++ [ "--disable-posix-spawn" ];
};)}

So far so good, I have make, it works on-device. But I’d like to use it for all on-device builds and still use the hydra cache. If I overlay a self: super: { gnumake = working-make; }, it starts rebuilding the whole system, and this absolutely isn’t something I can expect everyone to do on their phone. I’ve looked into replaceDependency, as it sounds like something that might save me, but I can’t figure out how to apply it to stdenv

self: super: { stdenv = super.replaceDependency {
  drv = super.stdenv;
  oldDependency = super.gnumake;
  newDependency = super.working-gnumake;
};}

leaves me with “infinite recursion encountered”.

So far my questions are:

  1. how do I use replaceDependency on stdenv?
  2. how horrible is that idea anyway?
  3. can I somehow fake other uses of gnumake that don’t go through stdenv?
  4. what are my options besides
    a. aforementioned grafting of stdenv
    b. trying to convince nixpkgs to --disable-posix-spawn for everybody
    c. merging Nix-on-Droid into nixpkgs the way Darwin works and trying to convince whoever runs hydra to build Nix-on-Droid variant as well
    d. getting a PhD in applied lunacy and fixing the real failure in… somewhere in there
    e. giving up
  5. and what do you think of them?
2 Likes

Random thought: maybe something like nix’s pre-build-hook could save the day as well, but I’m not sure if it has any effect as we don’t sandbox in Nix-on-Droid due to the lack of root.

I went down the applied lunacy rabbit hole and fixed it in proot. It was not as deep as I anticipated, but still quite a gap between “new gnumake started crashing” and “let’s just trap this SECCOMP denial, peek some CPU registers and hope we can fake this syscall”. With freshly released nix-on-droid 21.05 you can again enjoy partaking in painstakingly long on-device compilations!

4 Likes