Skip to content

fix(linux): make the Linux build work on arm64 - #293

Open
zebster-cmd wants to merge 1 commit into
getopenscreen:mainfrom
zebster-cmd:fix/linux-arm64-build
Open

fix(linux): make the Linux build work on arm64#293
zebster-cmd wants to merge 1 commit into
getopenscreen:mainfrom
zebster-cmd:fix/linux-arm64-build

Conversation

@zebster-cmd

@zebster-cmd zebster-cmd commented Aug 6, 2026

Copy link
Copy Markdown

Summary

npm run build:linux cannot complete on an aarch64 host. This fixes four independent x86-only assumptions in the Linux build path, so the same command produces a working arm64 deb/AppImage.

Change Problem it fixes
scripts/fetch-ffmpeg.mjs SHARED_PINNED has no linux-arm64 entry, so the SDK fetch bails. BtbN publishes the asset in the already-pinned release — only the pin was missing. Digest taken from that release's checksums.sha256.
scripts/build-linux-compositor-addon.mjs /usr/lib/x86_64-linux-gnu and /usr/lib/gcc/x86_64-linux-gnu are hardcoded, hiding both libclang and gcc's stddef.h on arm64. Now derived from process.arch.
scripts/build-linux-pipewire-helper.mjs bindgen dies with 'limits.h' file not found — Ubuntu ships libclang.so.1 with no resource dir. Now passes BINDGEN_EXTRA_CLANG_ARGS at gcc's includes, the same fallback build-linux-compositor-addon.mjs already applies.
crates/compositor/src/audio.rs, electron/native/pipewire-capture/src/ffmpeg.rs [0i8; 256] passed to av_strerror's *mut c_char. c_char is signed on x86_64 but unsigned on aarch64, so this is a hard type error there. Uses c_char.

No behaviour change on x86_64: the ffmpeg pin is additive, both path constants resolve to their previous values, and c_char is i8 there.

Related issue

No existing issue — found while building for an aarch64 machine.

Type of change

  • Bug fix
  • Feature
  • Enhancement
  • Documentation
  • Refactor / maintenance
  • Performance
  • Security

Release impact

  • Patch
  • Minor
  • Major / breaking change
  • No release note needed

Desktop impact

  • Windows
  • macOS
  • Linux
  • Installer / packaging

Screenshots / video

No visual change. The packaged arm64 build boots and renders its recorder toolbar correctly under Xvfb.

Testing

Ubuntu 24.04, aarch64 (NVIDIA GB10), Rust 1.95, Node 22.22.

Build & packagenpm run build:linux

  • Openscreen-Linux-1.9.0.debArchitecture: arm64; apt-get -s install resolves every dependency with no extras.
  • Installs and launches with the Chromium sandbox enabled (no --no-sandbox), and renders under xvfb-run.

Unitnpm test1677 passed, 1 skipped, 0 failed (140 files).

E2Enpm run test:e2e under xvfb-run7 passed, 4 skipped, 0 failed. The 4 skips are windows-native-checklist.spec.ts (test.skip(process.platform !== "win32")).

Both export paths pass end-to-end on arm64:

  • exports an MP4 from a loaded video — software libopenh264
  • exports a GIF from a loaded video — compositor selected the hardware backend: [d3d] adaptateur Vulkan : NVIDIA GB10 (IntegratedGpu, Vulkan) -> backend Hardware

That last line is the useful one: the natively-built compositor addon negotiates a hardware Vulkan backend on arm64, not just a CPU fallback.

Staticnpx tsc clean; biome check clean on the three changed scripts. cargo test in pipewire-capture: 54 passed, 1 failed — see below.

Not verified on x86_64 (no host available), though the reasoning for why each change is a no-op there is above.

Note for anyone reproducing the e2e run on Linux

npm run dev aborts before serving because node_modules/electron/dist/chrome-sandbox isn't root:root 4755, which takes the Vite server down with it and fails every spec on ERR_CONNECTION_REFUSED. NO_ELECTRON=1 npm run dev avoids it. Pre-existing and unrelated to arm64 — mentioning it only so the run is reproducible.

One caveat, not fixed here

BtbN's linuxarm64 ffmpeg ships no h264_vaapi, so every_ladder_entry_names_a_codec_this_build_has fails on arm64. The encoder ladder probes and falls through at runtime, and h264_nvenc, h264_v4l2m2m and libopenh264 are all present — so this looks like a gap in the test's assumption rather than a broken export path. Left alone to keep this PR to the build fix; happy to follow up if you'd like the assertion made arch-aware.

🤖 Generated with Claude Code

https://claude.ai/code/session_014iYUHw6DyT4CSBNyvr4zsY

Summary by CodeRabbit

  • Bug Fixes

    • Improved audio error handling compatibility across supported CPU architectures.
    • Fixed architecture-specific Linux build configuration for ARM64 and x86_64 systems.
  • New Features

    • Added support for provisioning shared FFmpeg on Linux ARM64.
    • Improved automatic compiler include-path detection for Linux builds.

`npm run build:linux` could not complete on an aarch64 host. Four
independent x86-only assumptions, each fixed here:

- fetch-ffmpeg: SHARED_PINNED had no `linux-arm64` entry, so the SDK
  fetch bailed out. BtbN publishes the asset in the pinned release;
  only the pin was missing. Digest taken from its checksums.sha256.
- build-linux-compositor-addon: `/usr/lib/x86_64-linux-gnu` and
  `/usr/lib/gcc/x86_64-linux-gnu` were hardcoded, hiding both libclang
  and gcc's stddef.h on arm64. Derived from `process.arch` instead.
- build-linux-pipewire-helper: bindgen failed with "'limits.h' file not
  found" because Ubuntu ships libclang.so.1 without a resource dir. Now
  passes BINDGEN_EXTRA_CLANG_ARGS at gcc's includes, the same fallback
  build-linux-compositor-addon already applied.
- audio.rs / ffmpeg.rs: `[0i8; 256]` passed to av_strerror's
  `*mut c_char`. `c_char` is signed on x86_64 but unsigned on aarch64,
  so this is a hard type error there. Use `c_char`.

No behaviour change on x86_64: the ffmpeg pin is additive, the two path
constants resolve to their previous values, and `c_char` *is* `i8` there.

Verified by building and packaging on aarch64 (Ubuntu 24.04): the deb
reports `Architecture: arm64`, and the app boots and renders under Xvfb.

One caveat worth flagging separately: BtbN's linuxarm64 ffmpeg ships no
h264_vaapi, so `every_ladder_entry_names_a_codec_this_build_has` fails on
arm64. The encoder ladder probes and falls through at runtime, and
h264_nvenc / h264_v4l2m2m / libopenh264 are all present, so this is a
gap in the test's assumption rather than a broken export path. Left
alone here to keep this PR to the build fix.
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bcd11237-d459-48d9-a739-23585ee907c0

📥 Commits

Reviewing files that changed from the base of the PR and between e3dbb4c and f006525.

📒 Files selected for processing (5)
  • crates/compositor/src/audio.rs
  • electron/native/pipewire-capture/src/ffmpeg.rs
  • scripts/build-linux-compositor-addon.mjs
  • scripts/build-linux-pipewire-helper.mjs
  • scripts/fetch-ffmpeg.mjs

📝 Walkthrough

Walkthrough

The PR adds Linux ARM64 support for FFmpeg provisioning and bindgen paths. It also replaces hardcoded i8 FFmpeg error buffers with platform-specific c_char buffers.

Changes

Linux ARM64 support

Layer / File(s) Summary
Platform-compatible FFmpeg error buffers
crates/compositor/src/audio.rs, electron/native/pipewire-capture/src/ffmpeg.rs
FFmpeg error buffers now use c_char instead of hardcoded i8.
Architecture-aware Linux bindgen setup
scripts/build-linux-compositor-addon.mjs, scripts/build-linux-pipewire-helper.mjs
Build scripts detect the host multiarch triplet and use architecture-specific libclang and GCC include paths. Existing BINDGEN_EXTRA_CLANG_ARGS values remain supported.
Pinned ARM64 FFmpeg provisioning
scripts/fetch-ffmpeg.mjs
Shared FFmpeg provisioning now includes a pinned Linux ARM64 archive and SHA-256 digest.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: etiennelescot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the Linux ARM64 build fix.
Description check ✅ Passed The description includes the required sections and provides detailed scope, impact, testing results, and a documented known caveat.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@zebster-cmd
zebster-cmd marked this pull request as ready for review August 6, 2026 14:25
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