Skip to content

fix: resolve native module architecture mismatch in Linux ARM64 builds#1055

Open
yunho0130 wants to merge 1 commit intopinokiocomputer:mainfrom
yunho0130:fix/linux-arm64-native-modules
Open

fix: resolve native module architecture mismatch in Linux ARM64 builds#1055
yunho0130 wants to merge 1 commit intopinokiocomputer:mainfrom
yunho0130:fix/linux-arm64-native-modules

Conversation

@yunho0130
Copy link

Summary

  • Fix Linux ARM64 packages shipping with x86-64 native .node modules, which causes immediate crash on ARM64 systems
  • Add fix-native-modules.js afterPack hook that detects cross-compilation and replaces mismatched binaries
  • Affected modules: @homebridge/node-pty-prebuilt-multiarch, @parcel/watcher, bufferutil

Problem

When building Linux ARM64 .deb/.rpm/.AppImage packages from an x86-64 Docker host (electronuserland/builder), native .node modules are compiled for x86-64 and incorrectly bundled into the ARM64 package.

Root cause: electron-builder install-app-deps runs once for the host architecture (process.arch = x64), and @electron/rebuild skips prebuilt modules (via prebuildInstallNativeModuleExists()) without verifying the target architecture matches.

Runtime errors on ARM64:

Error: /opt/Pinokio/resources/app.asar.unpacked/node_modules/@homebridge/
  node-pty-prebuilt-multiarch/build/Release/pty.node: cannot open shared object file
Error: /opt/Pinokio/resources/app.asar.unpacked/node_modules/@parcel/
  watcher/build/Release/watcher.node: cannot open shared object file

Solution

Add a fix-native-modules.js afterPack hook (called from after-pack.js) that:

  1. Detects cross-compilation by comparing host and target architectures
  2. Scans all .node files in app.asar.unpacked using the file command to check ELF architecture
  3. Replaces mismatched binaries using three strategies:
    • Prebuilds: Copy from the package's prebuilds/linux-<arch>/ directory (e.g. node-pty)
    • Platform packages: Download the correct platform-specific npm package (e.g. @parcel/watcher-linux-arm64-glibc)
    • Cross-compile: Build N-API modules with cross-compiler when available (e.g. bufferutil)

The hook is a no-op when host and target architectures match (no performance impact for native builds).

Test plan

  • Verified on Ubuntu 24.04 ARM64 (aarch64) that v6.0.10 ARM64 .deb ships x86-64 native modules
  • Manually replaced all three modules (pty.node, watcher.node, bufferutil.node) with ARM64 versions
  • Confirmed Pinokio starts and runs successfully on ARM64 after replacement
  • Build Linux packages from x86-64 Docker with this patch and verify ARM64 output

🤖 Generated with Claude Code

When building Linux ARM64 packages from an x86-64 host (e.g. Docker),
native .node modules (node-pty, @parcel/watcher, bufferutil) are
compiled for x86-64 and incorrectly bundled into the ARM64 package.

This happens because electron-builder's install-app-deps runs once for
the host architecture, and @electron/rebuild skips prebuilt modules
without verifying the target architecture.

Add a fix-native-modules.js afterPack hook that:
- Detects cross-compilation (host arch != target arch)
- Scans all active .node files in app.asar.unpacked for arch mismatches
- Replaces mismatched binaries from prebuilds/ directories (node-pty)
- Downloads correct platform-specific npm packages (@parcel/watcher)
- Cross-compiles N-API modules when toolchain is available (bufferutil)

Tested on Ubuntu 24.04 ARM64 (aarch64) with Pinokio v6.0.10.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant