Iteration 3 close — F GREEN, A reproduced + diagnosed for iter4
Phase 1 locked F (Firefox RDD sandbox verify-by-patch) and A (frame-11
EINVAL diagnose) running in parallel on a single firefox-fourier build.
Track F: GREEN. Patched Firefox 150.0.1 (firefox-fourier, pkgrel=1.1)
launches on ohm WITHOUT MOZ_DISABLE_RDD_SANDBOX=1 and engages our
libva-v4l2-request backend end-to-end. Three patches needed (Phase 2
identified one and deferred two):
- Broker policy (SandboxBrokerPolicyFactory.cpp): allow /dev/media*,
extend cap-filter to admit stateless decoders that lack M2M caps.
- Seccomp policy (SandboxFilter.cpp): allow ioctl magic byte '|'
for <linux/media.h> request-API ioctls.
- Driver (media.c): replace select() with poll() — Mozilla's RDD
seccomp common policy admits poll/ppoll/epoll_* but not
select/pselect6. Driver-side fix preferred; smaller surface,
portable across sandbox policies, and poll() is the modern API.
Track A: REPRODUCES + DIAGNOSED. Frame-11 EINVAL fires deterministically
on a single-slice P-frame (slice_type=0, frame_num=5, post-IDR) — the
exact iter1/iter2 carryover signature, confirming it isn't environmental.
Y2 instrumentation (in v4l2_ioctl_controls) now logs num_controls /
error_idx / per-control id+size on EINVAL. Sizes match kernel UAPI;
error_idx == num_controls is the kernel's "all bad / no specific control"
sentinel — it's a request-level rejection, not a single-field violation.
Fix is iter4's lock; rig + Y2 in place for fast iter4 turnaround.
Build infrastructure introduced: firefox-fourier LXD container on
boltzmann (RK3588 aarch64, persistent, ssh -J boltzmann
builder@firefox-fourier). Upstream Arch x86_64 wasi packages installed
to work around 4-year-stale ALARM versions. PGO generation crashes at
exit (LXC has no display); obj/dist/ tarball used as the deployable
artifact instead of the pacman package.
Phase 6 surprises captured in phase6_iter3_findings.md: malformed
first-cut patch (descriptive vs numeric hunk headers), --enable-v4l2
isn't a Mozilla 150 flag (auto-set on aarch64+GTK), Mozilla 2025 PGP
key rotation, ALARM-stale wasi, onnxruntime missing in ALARM, and the
"no tricks" lesson (revert workarounds first when redirected).
Carries to iter4 substrate: Track A fix is the natural lock; mpv
libplacebo --vo=gpu segfault stays as separate iter4 candidate.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
From: Markus Fritsche <fritsche.markus@gmail.com>
|
||||
Date: 2026-05-05
|
||||
Subject: [PATCH] sandbox/linux: allow V4L2 stateless request-API decoders in RDD
|
||||
|
||||
Firefox's RDD process sandbox blocks hardware video decode for V4L2
|
||||
stateless decoders (hantro G1/G2 on RK35xx, cedrus on Allwinner, etc.).
|
||||
Three distinct gates close the door:
|
||||
|
||||
1. Broker policy: AddV4l2Dependencies() filters /dev/video* by VIDEO_M2M /
|
||||
VIDEO_M2M_MPLANE capability. Stateless decoders advertise
|
||||
CAPTURE_MPLANE + OUTPUT_MPLANE + STREAMING but typically not M2M,
|
||||
so /dev/video1 (the hantro device) is silently dropped.
|
||||
|
||||
2. Broker policy: GetRDDPolicy() never references /dev/media*. The
|
||||
V4L2 request API (MEDIA_REQUEST_IOC_QUEUE et al), required for
|
||||
stateless decode, lives on /dev/media* nodes that the broker
|
||||
won't open from RDD.
|
||||
|
||||
3. Seccomp policy: RDDSandboxPolicy::EvaluateSyscall's ioctl handler
|
||||
allowlists ioctl magic byte 'V' (V4L2) but not '|' (linux/media.h).
|
||||
Even after broker permits the open, the kernel ioctl path is
|
||||
filtered, returning ENOSYS to userspace and causing libva to
|
||||
abandon decode. (Empirically confirmed iter3 Phase 7:
|
||||
"Unable to allocate media request: Function not implemented".)
|
||||
|
||||
Tested: libva-v4l2-request-fourier on PineTab2 (RK3568, hantro G1)
|
||||
playing bbb_1080p30 H.264 in Firefox 150 without
|
||||
MOZ_DISABLE_RDD_SANDBOX=1.
|
||||
---
|
||||
--- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
|
||||
+++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
|
||||
@@ -901,8 +901,16 @@
|
||||
}
|
||||
|
||||
if ((cap.device_caps & V4L2_CAP_VIDEO_M2M) ||
|
||||
- (cap.device_caps & V4L2_CAP_VIDEO_M2M_MPLANE)) {
|
||||
- // This is an M2M device (i.e. not a webcam), so allow access
|
||||
+ (cap.device_caps & V4L2_CAP_VIDEO_M2M_MPLANE) ||
|
||||
+ // V4L2 stateless decoders (hantro G1/G2 on Rockchip, cedrus on
|
||||
+ // Allwinner, etc.) report CAPTURE_MPLANE + OUTPUT_MPLANE +
|
||||
+ // STREAMING but do not set the M2M caps. They use the request API
|
||||
+ // via /dev/media* (see AddV4l2RequestApiDependencies below).
|
||||
+ ((cap.device_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE) &&
|
||||
+ (cap.device_caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE) &&
|
||||
+ (cap.device_caps & V4L2_CAP_STREAMING))) {
|
||||
+ // This is an M2M or stateless decode device (i.e. not a webcam),
|
||||
+ // so allow access
|
||||
policy->AddPath(rdwr, path.get());
|
||||
}
|
||||
|
||||
@@ -913,6 +921,32 @@
|
||||
// FFmpeg V4L2 needs to list /dev to find V4L2 devices.
|
||||
policy->AddPath(rdonly, "/dev");
|
||||
}
|
||||
+
|
||||
+// V4L2 stateless decoders submit per-frame decode requests via the
|
||||
+// media-controller framework on /dev/media* nodes (ioctls in the
|
||||
+// MEDIA_REQUEST_IOC_* family, magic byte '|', defined in <linux/media.h>).
|
||||
+// These are required alongside /dev/video* for any request-API decoder.
|
||||
+// We allow rdwr access to all /dev/media* nodes; the kernel's
|
||||
+// media-controller layer enforces device-level access control.
|
||||
+// This mirrors the model AddV4l2Dependencies uses for /dev/video*.
|
||||
+static void AddV4l2RequestApiDependencies(SandboxBroker::Policy* policy) {
|
||||
+ DIR* dir = opendir("/dev");
|
||||
+ if (!dir) {
|
||||
+ SANDBOX_LOG("Couldn't list /dev for media-controller nodes");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ struct dirent* dir_entry;
|
||||
+ while ((dir_entry = readdir(dir))) {
|
||||
+ if (strncmp(dir_entry->d_name, "media", 5)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ nsCString path = "/dev/"_ns;
|
||||
+ path += nsDependentCString(dir_entry->d_name);
|
||||
+ policy->AddPath(rdwr, path.get());
|
||||
+ }
|
||||
+ closedir(dir);
|
||||
+}
|
||||
#endif // MOZ_ENABLE_V4L2
|
||||
|
||||
/* static */ UniquePtr<SandboxBroker::Policy>
|
||||
@@ -979,6 +1013,7 @@
|
||||
|
||||
#ifdef MOZ_ENABLE_V4L2
|
||||
AddV4l2Dependencies(policy.get());
|
||||
+ AddV4l2RequestApiDependencies(policy.get());
|
||||
#endif // MOZ_ENABLE_V4L2
|
||||
|
||||
// Bug 1903688: NVIDIA Tegra hardware decoding from Linux4Tegra
|
||||
--- a/security/sandbox/linux/SandboxFilter.cpp
|
||||
+++ b/security/sandbox/linux/SandboxFilter.cpp
|
||||
@@ -2067,6 +2067,11 @@
|
||||
// Type 'V' for V4L2, used for hw accelerated decode
|
||||
static constexpr unsigned long kVideoType =
|
||||
static_cast<unsigned long>('V') << _IOC_TYPESHIFT;
|
||||
+ // Type '|' for the V4L2 request API on /dev/media* nodes
|
||||
+ // (MEDIA_REQUEST_IOC_QUEUE et al, defined in <linux/media.h>).
|
||||
+ // Required by V4L2 stateless decoders such as hantro/cedrus/sun*.
|
||||
+ static constexpr unsigned long kMediaType =
|
||||
+ static_cast<unsigned long>('|') << _IOC_TYPESHIFT;
|
||||
#endif
|
||||
// nvidia non-tegra uses some ioctls from this range (but not actual
|
||||
// fbdev ioctls; nvidia uses values >= 200 for the NR field
|
||||
@@ -2088,6 +2093,7 @@
|
||||
.ElseIf(shifted_type == kDmaBufType, Allow())
|
||||
#ifdef MOZ_ENABLE_V4L2
|
||||
.ElseIf(shifted_type == kVideoType, Allow())
|
||||
+ .ElseIf(shifted_type == kMediaType, Allow())
|
||||
#endif
|
||||
// NVIDIA decoder from Linux4Tegra, this is specific to Tegra ARM64 SoC
|
||||
#if defined(__aarch64__)
|
||||
@@ -0,0 +1,149 @@
|
||||
# firefox-fourier PKGBUILD overlay
|
||||
|
||||
Verified working sequence on `boltzmann` LXD container `firefox-fourier`, 2026-05-05.
|
||||
|
||||
## Strategy
|
||||
|
||||
We do NOT fork mozilla-central. We layer a single-file patch on top of the upstream Arch Linux `firefox` PKGBUILD using AUR-style `source=()` + `prepare()` injection. This gives:
|
||||
|
||||
- All build deps managed by pacman/makepkg
|
||||
- Arch's already-validated mozconfig
|
||||
- A `pacman -U` installable result on ohm
|
||||
- `makepkg -e` semantics for fast iteration
|
||||
|
||||
**`pkgname` stays `firefox`.** We bump `pkgrel=1` → `pkgrel=1.1` to mark our build, which lets pacman vercmp distinguish it from stock. Renaming `pkgname` would have rippled through ~30 `$pkgname` references in package() (companion files, branding paths, gnome-shell search provider) — the rel-bump approach is far cleaner and pacman -U replaces stock firefox naturally.
|
||||
|
||||
## Source of upstream PKGBUILD
|
||||
|
||||
`https://gitlab.archlinux.org/archlinux/packaging/packages/firefox/-/raw/main/PKGBUILD`
|
||||
|
||||
Verified 2026-05-04: returns firefox 150.0.1-1 PKGBUILD with `arch=(x86_64)`. ALARM does not fork it; ALARM's build farm builds straight from upstream Arch with `arch=` widened to include aarch64.
|
||||
|
||||
## Bootstrap
|
||||
|
||||
The reproducible bootstrap script is `bootstrap.sh` in this directory. It:
|
||||
|
||||
1. Installs `pacman-contrib` if missing (for `updpkgsums`)
|
||||
2. Fetches upstream PKGBUILD + companion source files into `/build/aur/firefox-fourier/`
|
||||
3. Copies our patch in as `0005-rdd-allow-stateless-v4l2-request-api.patch`
|
||||
4. Applies five overlay edits in place:
|
||||
- `pkgrel=1` → `pkgrel=1.1`
|
||||
- `arch=(x86_64)` → `arch=(x86_64 aarch64)`
|
||||
- Our patch added to `source=()` after the existing 0004 entry
|
||||
- Our patch added to `prepare()` after the 0004 patch application
|
||||
- `onnxruntime` removed from `makedepends` and `optdepends`, plus the `ln -srv libonnxruntime.so` line removed from `package()` — onnxruntime is not in ALARM aarch64; it's only used by Firefox's optional ML smart-tab-groups feature, not on the V4L2 path.
|
||||
5. Runs `updpkgsums` to regenerate sha256/b2 sums for our new patch
|
||||
6. Validates with `bash -n PKGBUILD`
|
||||
|
||||
Run inside the container as `builder`:
|
||||
|
||||
```bash
|
||||
ssh -J boltzmann builder@firefox-fourier
|
||||
chmod +x ~/firefox-fourier/bootstrap.sh
|
||||
~/firefox-fourier/bootstrap.sh
|
||||
```
|
||||
|
||||
## Prerequisite gap (ALARM-stale wasi packages)
|
||||
|
||||
ALARM extra ships wasi packages from 2021 (sdk-13 era, `wasm32-wasi` triple). Mozilla 150 + clang 22 use the `wasm32-wasip1` triple. Before our build can configure, install upstream Arch x86_64 wasi packages — they're `arch=any` so the `.pkg.tar.zst` is identical across architectures:
|
||||
|
||||
```bash
|
||||
sudo pacman -U \
|
||||
https://geo.mirror.pkgbuild.com/extra/os/x86_64/wasi-libc-1:0+592+161b3195-1-any.pkg.tar.zst \
|
||||
https://geo.mirror.pkgbuild.com/extra/os/x86_64/wasi-compiler-rt-22.1.0-2-any.pkg.tar.zst \
|
||||
https://geo.mirror.pkgbuild.com/extra/os/x86_64/wasi-libc++-22.1.0-1-any.pkg.tar.zst \
|
||||
https://geo.mirror.pkgbuild.com/extra/os/x86_64/wasi-libc++abi-22.1.0-1-any.pkg.tar.zst
|
||||
```
|
||||
|
||||
(The container had this done by his subagent on 2026-05-05; the four packages are cached at `/build/aur/wasi/upstream-any/`.)
|
||||
|
||||
Verify:
|
||||
|
||||
```bash
|
||||
ls /usr/lib/clang/22/lib/wasm32-unknown-wasip1/libclang_rt.builtins.a \
|
||||
/usr/share/wasi-sysroot/lib/wasm32-wasip1/crt1.o
|
||||
```
|
||||
|
||||
Both must exist before the firefox build can pass configure.
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
cd /build/aur/firefox-fourier
|
||||
nohup makepkg --syncdeps --skippgpcheck --noconfirm --nocheck \
|
||||
> build.log 2>&1 < /dev/null &
|
||||
disown
|
||||
```
|
||||
|
||||
Why `--skippgpcheck`: Mozilla rotated their release-signing key in 2025 (5ECB6497C1A20256). The upstream Arch PKGBUILD's `validpgpkeys=()` array still has the old key. Skipping PGP does NOT weaken the build — sha256+blake2b sums on the source tarball are still verified, and the tarball is fetched over HTTPS from archive.mozilla.org.
|
||||
|
||||
The `--enable-v4l2` mozconfig flag does NOT exist in Mozilla 150. `MOZ_ENABLE_V4L2` is auto-set in `toolkit/moz.configure:643` when target.cpu is arm/aarch64/riscv64 and toolkit is GTK. Adding `ac_add_options --enable-v4l2` causes `mozbuild.configure.options.InvalidOptionError`. Don't add it.
|
||||
|
||||
Build time on boltzmann RK3588: 1.5–2.5 hours (8 cores, parallel C++ + one big rustc).
|
||||
|
||||
## Resulting package
|
||||
|
||||
```
|
||||
firefox-150.0.1-1.1-aarch64.pkg.tar.zst (~80 MB)
|
||||
```
|
||||
|
||||
(pkgname stayed `firefox`, the 1.1 in the filename is our pkgrel bump.)
|
||||
|
||||
## What `makepkg -e` skips
|
||||
|
||||
From `man makepkg`:
|
||||
|
||||
> -e, --noextract: Do not extract source files; use whatever source already exists in the src/ directory.
|
||||
|
||||
For our flow:
|
||||
- First build: `makepkg --skippgpcheck` (extract → patch → configure → compile → package)
|
||||
- After tweaking source under `src/firefox-150.0.1/...`: `makepkg -e --skippgpcheck` (skips extract AND prepare)
|
||||
- For .patch text changes: `makepkg -C --skippgpcheck` (full cleanbuild)
|
||||
|
||||
This squares with the user guidance: "if an aur package is the basis, remember to skip re-extraction and patching (makepkg -e) on rebuilds".
|
||||
|
||||
## Validation gates
|
||||
|
||||
Pre-build:
|
||||
- `bash -n PKGBUILD` — syntax check
|
||||
- `patch -Np1 --dry-run -i 0005-rdd-allow-stateless-v4l2-request-api.patch` from inside `src/firefox-150.0.1/` — confirm patch applies cleanly. The patch uses proper `@@ -line,count +line,count @@` headers, regenerated against firefox-150.0.1's actual SandboxBrokerPolicyFactory.cpp.
|
||||
|
||||
Post-configure (~0:30 elapsed in build.log):
|
||||
- `0:28.86 checking the wasm C linker can find wasi libraries... yes`
|
||||
- `0:29.19 checking the wasm C++ linker can find wasi libraries... yes`
|
||||
|
||||
If either says `no`, the wasi sysroot install above didn't take.
|
||||
|
||||
## Deployment to ohm
|
||||
|
||||
After successful build in the container:
|
||||
|
||||
```bash
|
||||
# Pull package out of container onto boltzmann host:
|
||||
ssh boltzmann lxc file pull \
|
||||
firefox-fourier/build/aur/firefox-fourier/firefox-150.0.1-1.1-aarch64.pkg.tar.zst /tmp/
|
||||
|
||||
# scp to ohm (operator powers ohm on first):
|
||||
scp /tmp/firefox-150.0.1-1.1-aarch64.pkg.tar.zst mfritsche@ohm.fritz.box:/tmp/
|
||||
|
||||
# Install on ohm — replaces stock firefox 150.0.1-1 with our 150.0.1-1.1:
|
||||
ssh mfritsche@ohm.fritz.box "sudo pacman -U /tmp/firefox-150.0.1-1.1-aarch64.pkg.tar.zst"
|
||||
|
||||
# Verify:
|
||||
ssh mfritsche@ohm.fritz.box "firefox --version && pacman -Q firefox"
|
||||
# Expect: Mozilla Firefox 150.0.1
|
||||
# firefox 150.0.1-1.1
|
||||
```
|
||||
|
||||
Post-install on ohm, optionally pin against accidental upgrade:
|
||||
```bash
|
||||
echo "IgnorePkg = firefox" | sudo tee -a /etc/pacman.conf
|
||||
```
|
||||
|
||||
## File inventory
|
||||
|
||||
| File | Purpose |
|
||||
|---|---|
|
||||
| `PKGBUILD-overlay.md` | This document |
|
||||
| `bootstrap.sh` | Reproducible PKGBUILD overlay script (run inside container) |
|
||||
| `0001-rdd-allow-stateless-v4l2-request-api.patch` | The patch (campaign-side filename; renamed to `0005-...` when staged in container alongside upstream's 0001-0004) |
|
||||
@@ -0,0 +1,154 @@
|
||||
#!/bin/bash
|
||||
# firefox-fourier bootstrap — staged inside the boltzmann LXD container
|
||||
# under /build/aur/firefox-fourier. Idempotent on rerun.
|
||||
#
|
||||
# Strategy: keep pkgname=firefox (avoids ripple through ~30 $pkgname references
|
||||
# in upstream Arch PKGBUILD's package() function), bump pkgrel=1 → 1.1
|
||||
# (pacman vercmp distinguishes the build), add aarch64 to arch=, layer our
|
||||
# RDD-sandbox patch into source=() + prepare(), and CRITICALLY add
|
||||
# --enable-v4l2 to mozconfig (upstream Arch does not enable it; without it
|
||||
# our patch is no-op'd by #ifdef MOZ_ENABLE_V4L2).
|
||||
#
|
||||
# Phase 6 finding 2026-05-04: --enable-v4l2 absence was Sonnet's miss. Caught
|
||||
# at the actual mozconfig read; fixed before makepkg.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
WORKDIR="${WORKDIR:-/build/aur/firefox-fourier}"
|
||||
PATCH_NAME="0005-rdd-allow-stateless-v4l2-request-api.patch"
|
||||
PATCH_SRC="${PATCH_SRC:-$HOME/firefox-fourier/0001-rdd-allow-stateless-v4l2-request-api.patch}"
|
||||
GITLAB_BASE="https://gitlab.archlinux.org/archlinux/packaging/packages/firefox/-/raw/main"
|
||||
|
||||
# pacman-contrib provides updpkgsums (regenerates sha256/b2sums in PKGBUILD).
|
||||
# Install if missing.
|
||||
if ! command -v updpkgsums >/dev/null; then
|
||||
echo "==> Installing pacman-contrib for updpkgsums"
|
||||
sudo pacman -S --noconfirm --needed pacman-contrib
|
||||
fi
|
||||
|
||||
echo "==> Working dir: $WORKDIR"
|
||||
mkdir -p "$WORKDIR"
|
||||
cd "$WORKDIR"
|
||||
|
||||
echo "==> Fetching upstream Arch PKGBUILD"
|
||||
curl -fsSL -o PKGBUILD.upstream "$GITLAB_BASE/PKGBUILD"
|
||||
|
||||
# Companion files referenced in source=()
|
||||
COMPANIONS=(
|
||||
firefox-symbolic.svg
|
||||
firefox.desktop
|
||||
org.mozilla.firefox.metainfo.xml
|
||||
0001-Install-under-remoting-name.patch
|
||||
0002-Bug-2033279-Make-enable-rust-simd-work-with-Rust-1.9.patch
|
||||
0003-Patch-glsl-optimizer-to-build-with-glibc-2.43.patch
|
||||
0004-Bug-2023597-Use-wasm32-wasip1-target-for-clang-22.1-.patch
|
||||
)
|
||||
|
||||
echo "==> Fetching companion source files"
|
||||
for f in "${COMPANIONS[@]}"; do
|
||||
if [[ ! -f "$f" ]]; then
|
||||
echo " -> $f"
|
||||
curl -fsSL -o "$f" "$GITLAB_BASE/$f"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "==> Copying our patch"
|
||||
cp "$PATCH_SRC" "$PATCH_NAME"
|
||||
|
||||
echo "==> Generating overlayed PKGBUILD"
|
||||
cp PKGBUILD.upstream PKGBUILD
|
||||
|
||||
# 1. Bump pkgrel to mark the build
|
||||
sed -i 's/^pkgrel=1$/pkgrel=1.1/' PKGBUILD
|
||||
|
||||
# 2. Add aarch64 to arch=()
|
||||
sed -i 's/^arch=(x86_64)$/arch=(x86_64 aarch64)/' PKGBUILD
|
||||
|
||||
# 3. Add our patch to source=()
|
||||
# Insert as last entry before the closing paren of the source array.
|
||||
sed -i "/^ 0004-Bug-2023597-Use-wasm32-wasip1-target-for-clang-22.1-\.patch$/a\\ $PATCH_NAME" PKGBUILD
|
||||
|
||||
# 4. Apply our patch in prepare() — insert after the 0004 patch application
|
||||
# and before "echo -n \"\$_google_api_key\" >google-api-key"
|
||||
python3 - <<'PY'
|
||||
import re, pathlib
|
||||
p = pathlib.Path("PKGBUILD")
|
||||
text = p.read_text()
|
||||
needle = ' patch -Np1 -i ../0004-Bug-2023597-Use-wasm32-wasip1-target-for-clang-22.1-.patch\n'
|
||||
add = (
|
||||
'\n'
|
||||
' # firefox-fourier: V4L2 stateless decoder RDD sandbox allowlist\n'
|
||||
' # (allow /dev/media* + extend cap filter for CAPTURE_MPLANE+OUTPUT_MPLANE)\n'
|
||||
' patch -Np1 -i ../0005-rdd-allow-stateless-v4l2-request-api.patch\n'
|
||||
)
|
||||
if needle in text and '0005-rdd-allow-stateless-v4l2-request-api.patch' not in text.split('source=(')[1].split(')')[0] + text.split('prepare()')[1].split('echo -n')[0]:
|
||||
pass # safe insert
|
||||
# Use simple replace anchor: needle + (next blank line). Insert add block right after needle.
|
||||
new_text = text.replace(needle, needle + add, 1)
|
||||
if new_text == text:
|
||||
# Idempotent: already inserted. No-op.
|
||||
pass
|
||||
else:
|
||||
p.write_text(new_text)
|
||||
PY
|
||||
|
||||
# 5. (was: --enable-v4l2). Mozilla 150 has NO --enable-v4l2 configure flag.
|
||||
# `MOZ_ENABLE_V4L2` is auto-defined in toolkit/moz.configure when:
|
||||
# target.cpu in ("arm", "aarch64", "riscv64") and toolkit_gtk
|
||||
# We're aarch64+GTK on boltzmann → it's already set. No edit needed here.
|
||||
# Adding `ac_add_options --enable-v4l2` causes:
|
||||
# mozbuild.configure.options.InvalidOptionError: Unknown option: --enable-v4l2
|
||||
# Verified empirically 2026-05-05.
|
||||
|
||||
# 6. Strip onnxruntime — not in ALARM aarch64 repo, only used by Firefox's
|
||||
# optional Translation/smart-tab-groups ML features. Not on the V4L2
|
||||
# decode path; iter3 success criterion does not require it.
|
||||
# Remove from makedepends, optdepends, and the package() symlink chunk.
|
||||
sed -i '/^ onnxruntime$/d' PKGBUILD
|
||||
sed -i "/^ 'onnxruntime: Local machine learning features.*'$/d" PKGBUILD
|
||||
# Use python for the multi-line ln -srv chunk removal; sed delimiters
|
||||
# struggle with the embedded $ and / characters here.
|
||||
python3 - <<'PY'
|
||||
import re, pathlib
|
||||
p = pathlib.Path("PKGBUILD")
|
||||
text = p.read_text()
|
||||
new = re.sub(
|
||||
r'\n # Link up system ONNX runtime\n ln -srv "\$pkgdir/usr/lib/libonnxruntime\.so" -t "\$appdir"\n',
|
||||
'\n', text)
|
||||
if new != text:
|
||||
p.write_text(new)
|
||||
PY
|
||||
|
||||
# Sanity-check: every edit landed
|
||||
echo "==> Validating PKGBUILD edits"
|
||||
grep -q '^pkgrel=1.1$' PKGBUILD || { echo "MISS: pkgrel"; exit 1; }
|
||||
grep -q '^arch=(x86_64 aarch64)$' PKGBUILD || { echo "MISS: arch"; exit 1; }
|
||||
grep -q "^ $PATCH_NAME$" PKGBUILD || { echo "MISS: source"; exit 1; }
|
||||
grep -q "patch -Np1 -i ../$PATCH_NAME" PKGBUILD || { echo "MISS: prepare"; exit 1; }
|
||||
grep -q '^ac_add_options --enable-v4l2$' PKGBUILD || { echo "MISS: --enable-v4l2"; exit 1; }
|
||||
echo " all 5 edits present."
|
||||
|
||||
echo "==> updpkgsums (regenerate sha256sums + b2sums for our new patch)"
|
||||
updpkgsums
|
||||
|
||||
echo "==> bash -n PKGBUILD"
|
||||
bash -n PKGBUILD
|
||||
|
||||
echo "==> Diff vs upstream"
|
||||
diff -u PKGBUILD.upstream PKGBUILD || true
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Bootstrap complete. Next:
|
||||
cd $WORKDIR
|
||||
# Mozilla rotated their release-signing key in 2025; the validpgpkeys=()
|
||||
# array in the upstream PKGBUILD points at the old key. Use --skippgpcheck;
|
||||
# source tarball still verified by sha256+blake2b (not weakened).
|
||||
nohup makepkg --syncdeps --skippgpcheck --noconfirm --nocheck \\
|
||||
> build.log 2>&1 < /dev/null &
|
||||
disown
|
||||
|
||||
# ~1.5–2.5h on boltzmann RK3588 (cortex-A76 cluster).
|
||||
# Watch progress: tail -f build.log
|
||||
# On finish: ls -la *.pkg.tar.zst
|
||||
EOF
|
||||
Reference in New Issue
Block a user