From 6568618811d08b08f459f3f2b495a8c716c28f9a Mon Sep 17 00:00:00 2001 From: Padreug Date: Fri, 25 Sep 2026 12:30:25 +0200 Subject: [PATCH] fix(nix): keep only the serialport prebuild this system can load The first ever aarch64 build of the app died here, on a Raspberry Pi 4: auto-patchelf could not satisfy dependency liblog.so wanted by node_modules/@serialport/bindings-cpp/prebuilds/android-arm64/node.napi.armv8.node auto-patchelf could not satisfy dependency libc++_shared.so wanted by (the same file) @serialport/bindings-cpp ships prebuilds for every platform it supports: android-arm, android-arm64, darwin, linux-arm, linux-arm64, linux-x64 in both glibc and musl, win32-ia32 and win32-x64. installPhase copied the whole directory. On x86_64 that was harmless because autoPatchelf skips ELF files whose architecture does not match the host, so the Android and ARM prebuilds were never touched. On aarch64 the android-arm64 prebuild IS the host architecture, so autoPatchelf picks it up and goes looking for Android's liblog.so and libc++_shared.so, which NixOS does not have. The failure was invisible until someone built for a second architecture. Keep only the prebuild the target can load, selected from stdenv.hostPlatform: linux-arm64 on aarch64, linux-x64 elsewhere, glibc rather than musl. Pruning rather than adding those two libraries to autoPatchelfIgnoreMissingDeps, which would have been the one-line fix. Teaching autoPatchelf to tolerate a binary we never load, for a platform we do not target, leaves the foreign prebuilds in the closure and leaves the same trap set for the next architecture. The existing "libc.musl-x86_64.so.1" entry in that list is this same problem solved the other way; it is now redundant, and is left in place only because this commit is unblocking a machine mid-build and is not the moment to find out whether something else depended on it. Verified on x86_64: the app still builds, ships linux-x64/node.napi.glibc.node alone where it previously carried nine platforms, and comes to 25M. --- nix/mkAtmApp.nix | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/nix/mkAtmApp.nix b/nix/mkAtmApp.nix index 68a4c37..272bd33 100644 --- a/nix/mkAtmApp.nix +++ b/nix/mkAtmApp.nix @@ -172,6 +172,27 @@ pkgs.stdenv.mkDerivation (finalAttrs: { cp -rL "$bcpp_store/node_modules/@serialport/bindings-cpp/prebuilds" $out/node_modules/@serialport/bindings-cpp/prebuilds cp "$bcpp_store/node_modules/@serialport/bindings-cpp/package.json" $out/node_modules/@serialport/bindings-cpp/package.json + # bindings-cpp ships prebuilds for every platform it supports: android, + # win32, darwin, and linux for several arches in both glibc and musl. Keep + # only the one this system can actually load. + # + # This is load-bearing on aarch64, not just tidiness. On x86_64 autoPatchelf + # skipped the foreign prebuilds because their ELF architecture did not match + # the host. On aarch64 the android-arm64 prebuild IS the host architecture, + # so autoPatchelf tries to patch it and fails hunting for Android's + # liblog.so and libc++_shared.so, which do not exist on NixOS. First Pi + # build died exactly there. + # + # Pruning rather than extending autoPatchelfIgnoreMissingDeps: teaching + # autoPatchelf to tolerate a binary we never load, for a platform we do not + # target, is the wrong shape of fix. The musl entry in that list below is + # the same problem solved the other way, and is now redundant. + keep_prebuild=${if pkgs.stdenv.hostPlatform.isAarch64 then "linux-arm64" else "linux-x64"} + find $out/node_modules/@serialport/bindings-cpp/prebuilds -mindepth 1 -maxdepth 1 \ + ! -name "$keep_prebuild" -exec rm -rf {} + + rm -f $out/node_modules/@serialport/bindings-cpp/prebuilds/*/*.musl.node + echo "serialport prebuilds kept: $(ls $out/node_modules/@serialport/bindings-cpp/prebuilds)/$(ls $out/node_modules/@serialport/bindings-cpp/prebuilds/"$keep_prebuild")" + copy_pnpm_pkg @serialport/bindings-interface $out/node_modules/@serialport/bindings-interface copy_pnpm_pkg @serialport/binding-mock $out/node_modules/@serialport/binding-mock