libva-v4l2-request-fourier-debian: pin trixie libva-dev for ABI #44

Merged
marfrit merged 2 commits from claude-noether/marfrit-packages:noether/libva-trixie-abi-pin into main 2026-05-20 12:59:40 +00:00
Contributor

Fix CI ABI skew between Arch runner and Debian target

Bug

libva-v4l2-request-fourier .deb currently unusable on Debian trixie. Built on the Arch CI runner where libva is 2.23 (VA-API 1.23), the driver exports __vaDriverInit_1_23. Trixie ships libva 2.22 (VA-API 1.22) and looks up __vaDriverInit_1_22. dlsym returns NULL, libva fallbacks to __vaDriverInit_1_0 (sentinel error name), and ffmpeg -hwaccel vaapi / vainfo / firefox-vaapi all fail to initialise on every Pi 5 / CM5 that installed the package.

Verified on higgs (Pi CM5, kernel 6.18.29+rpt-rpi-2712, libva-v4l2-request-fourier 1.0.0+r378+gc332d34-1 freshly installed): vainfo -> libva error has no function __vaDriverInit_1_0, vaInitialize -1.

Why libva but not ffmpeg

ffmpeg-v4l2-request-fourier (also built on Arch) links libva but does not EXPORT any vaDriverInit symbol — it just uses libva public API which is forward-compatible. libva-v4l2-request-fourier IS the driver and exports _vaDriverInit_, where the name is computed at compile time from <va/va.h>. So pkg-config CFLAGS pointing at Arch headers -> wrong symbol name -> loader cannot bind. readelf -d confirms the .so has no NEEDED entry for libva.so — only the symbol name matters.

Fix

debian/libva-v4l2-request-fourier/build-deb.sh now downloads libva-dev / libva2 / libva-drm2 from Debian archive (trixie 2.22.0-3 pin), extracts to a sysroot, rewrites pkgconfig prefixes, sets PKG_CONFIG_PATH so meson sees trixie headers regardless of runner libva-dev. Link step still resolves -lva against the sysroot libva.so.2 (any version works; resulting .so has no NEEDED libva entry).

Hard sanity check at end of build-deb.sh: fail the build if the produced .so does not export __vaDriverInit_1_22. Future ABI-skew failures loud at CI time instead of silent install-then-refuse-to-load.

Tested on boltzmann (aarch64) — sysroot build produces a .so exporting __vaDriverInit_1_22 (nm -D verified).

Source unchanged from c332d34; only build env differs. PKGREL 1 -> 2 (rebuild against pinned trixie libva-dev).

Companion / blast radius

LIBVA-2 unblocker — the runtime libva-bind failure has been masking the LIBVA-1 per-codec dispatch on higgs. Once the new -2 .deb lands on packages.reauktion.de, apt upgrade + daedalus daemon log + rpi-hevc-dec routing can be validated end-to-end.

Other libva-API consumers (ffmpeg-v4l2-request-fourier, mpv-fourier) do NOT have this bug — they only USE the libva API at source level, no symbol-name baking. No need to pin libva-dev for those.

🤖 Generated with Claude Code

## Fix CI ABI skew between Arch runner and Debian target ### Bug libva-v4l2-request-fourier .deb currently unusable on Debian trixie. Built on the Arch CI runner where libva is 2.23 (VA-API 1.23), the driver exports __vaDriverInit_1_23. Trixie ships libva 2.22 (VA-API 1.22) and looks up __vaDriverInit_1_22. dlsym returns NULL, libva fallbacks to __vaDriverInit_1_0 (sentinel error name), and ffmpeg -hwaccel vaapi / vainfo / firefox-vaapi all fail to initialise on every Pi 5 / CM5 that installed the package. Verified on higgs (Pi CM5, kernel 6.18.29+rpt-rpi-2712, libva-v4l2-request-fourier 1.0.0+r378+gc332d34-1 freshly installed): vainfo -> libva error has no function __vaDriverInit_1_0, vaInitialize -1. ### Why libva but not ffmpeg ffmpeg-v4l2-request-fourier (also built on Arch) links libva but does not EXPORT any vaDriverInit symbol — it just uses libva public API which is forward-compatible. libva-v4l2-request-fourier IS the driver and exports __vaDriverInit_<MAJOR>_<MINOR>, where the name is computed at compile time from <va/va.h>. So pkg-config CFLAGS pointing at Arch headers -> wrong symbol name -> loader cannot bind. readelf -d confirms the .so has no NEEDED entry for libva.so — only the symbol name matters. ### Fix debian/libva-v4l2-request-fourier/build-deb.sh now downloads libva-dev / libva2 / libva-drm2 from Debian archive (trixie 2.22.0-3 pin), extracts to a sysroot, rewrites pkgconfig prefixes, sets PKG_CONFIG_PATH so meson sees trixie headers regardless of runner libva-dev. Link step still resolves -lva against the sysroot libva.so.2 (any version works; resulting .so has no NEEDED libva entry). Hard sanity check at end of build-deb.sh: fail the build if the produced .so does not export __vaDriverInit_1_22. Future ABI-skew failures loud at CI time instead of silent install-then-refuse-to-load. Tested on boltzmann (aarch64) — sysroot build produces a .so exporting __vaDriverInit_1_22 (nm -D verified). Source unchanged from c332d34; only build env differs. PKGREL 1 -> 2 (rebuild against pinned trixie libva-dev). ### Companion / blast radius LIBVA-2 unblocker — the runtime libva-bind failure has been masking the LIBVA-1 per-codec dispatch on higgs. Once the new -2 .deb lands on packages.reauktion.de, apt upgrade + daedalus daemon log + rpi-hevc-dec routing can be validated end-to-end. Other libva-API consumers (ffmpeg-v4l2-request-fourier, mpv-fourier) do NOT have this bug — they only USE the libva API at source level, no symbol-name baking. No need to pin libva-dev for those. 🤖 Generated with Claude Code
claude-noether added 1 commit 2026-05-20 12:32:43 +00:00
The libva-v4l2-request-fourier .deb shipped with the wrong VA-API
symbol export because the CI runner is Arch (libva 2.23 = VA-API
1.23) while the install target is Debian trixie (libva 2.22 = VA-API
1.22).  At compile time, <va/va.h>'s VA_MAJOR/VA_MINOR macros are
baked into the driver's __vaDriverInit_<MAJOR>_<MINOR> symbol name.
trixie's libva runtime looks up __vaDriverInit_1_22, our driver only
exported __vaDriverInit_1_23, so dlsym() returned NULL and libva
fell back to its sentinel error "has no function __vaDriverInit_1_0".
Result: ffmpeg -hwaccel vaapi fails on startup, vainfo fails the
same way, on every Pi 5 / CM5 that installed the package.

The driver itself doesn't link libva.so (no NEEDED entry — confirmed
via readelf on higgs), so the only thing that matters is the symbol
NAME the compiler bakes in.  Fix is small: in build-deb.sh, download
trixie's libva-dev / libva2 / libva-drm2 .deb from deb.debian.org,
extract to a sysroot, rewrite the .pc prefixes, and set
PKG_CONFIG_PATH so pkg-config returns trixie headers regardless of
what the runner has installed.  The link step still resolves -lva
against the sysroot's libva.so.2, but the resulting .so has no
NEEDED entry for it.

Added a hard sanity check at the end of build-deb.sh: fail the build
if the produced .so doesn't export __vaDriverInit_1_22.  This makes
future ABI-skew failures loud at CI time instead of silent install-
then-refuse-to-load on the target.

Tested on boltzmann (aarch64): sysroot build produces a .so exporting
__vaDriverInit_1_22 (verified via nm -D).  Source unchanged from
c332d34; only the build env differs.

pkgver/upstream unchanged.  PKGREL bumped 1 -> 2 (rebuild against
pinned trixie libva-dev) so apt picks up the new .deb on higgs.

This is the LIBVA-2 unblocker — the runtime-libva-bind failure was
masking whether the LIBVA-1 per-codec dispatch actually works on
higgs.  Once -2 lands on packages.reauktion.de, apt upgrade on higgs
and the daedalus daemon log + rpi-hevc-dec dispatch can be validated
end-to-end.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Owner

Please check your fix - actrunner-debian-aarch64-bohr is available.

Please check your fix - actrunner-debian-aarch64-bohr is available.
claude-noether added 1 commit 2026-05-20 12:58:39 +00:00
Per @marfrit on PR #44 review: a native Debian trixie aarch64 runner
(debian-aarch64-bohr) is available — use it instead of the sysroot
hack from the previous commit.

The sysroot approach worked but was a workaround for not having the
right runner.  Native trixie runner is much cleaner:

  - libva-dev installs via apt-get directly from trixie's archive
    (2.22.0-3) — pkg-config returns trixie headers, driver compiles
    in __vaDriverInit_1_22 naturally.
  - No need to symlink libva.so.2 -> libva.so or rewrite .pc prefixes.
  - No bsdtar/ar/dpkg-deb juggling on an Arch runner that doesn't
    natively have dpkg.

Changes from PR v1:

  - .gitea/workflows/build.yml: libva-v4l2-request-fourier-debian
    runs-on: debian-aarch64-bohr (was arch-aarch64).  Build-deps
    installed via apt-get instead of pacman -Syu.

  - build-deb.sh: drop the sysroot download / pkgconfig rewrite /
    symlink block.  Keep the post-build ABI sanity check (nm -D |
    grep __vaDriverInit_1_22) — same defensive role as before, with
    an updated error message that points to the expected runner.

  - debian/.../changelog: -2 entry rewritten to describe the runner
    move instead of the sysroot.

Tested approach on boltzmann (aarch64): meson build against trixie
sysroot produces __vaDriverInit_1_22 (proves the source compiles
correctly with VA-API 1.22 headers).  Native runner build will
follow the same path, just without the explicit sysroot setup.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Author
Contributor

Thanks — switched the libva-v4l2-request-fourier-debian job to runs-on: debian-aarch64-bohr (051da5e8d on the branch). Dropped the sysroot download from build-deb.sh; native trixie libva-dev (2.22) gives us __vaDriverInit_1_22 naturally. Kept the post-build nm -D sanity check so a future runner change can not silently regress.

Follow-up commit on top of v1 (no force-push) so the review thread keeps both approaches visible. Ready for re-review.

Thanks — switched the libva-v4l2-request-fourier-debian job to **runs-on: debian-aarch64-bohr** (051da5e8d on the branch). Dropped the sysroot download from build-deb.sh; native trixie libva-dev (2.22) gives us __vaDriverInit_1_22 naturally. Kept the post-build nm -D sanity check so a future runner change can not silently regress. Follow-up commit on top of v1 (no force-push) so the review thread keeps both approaches visible. Ready for re-review.
marfrit merged commit 1c77b05f68 into main 2026-05-20 12:59:40 +00:00
marfrit deleted branch noether/libva-trixie-abi-pin 2026-05-20 12:59:40 +00:00
Owner

Please amend the PR - runner is named "actrunner-debian-aarch64-bohr"

Please amend the PR - runner is named "actrunner-debian-aarch64-bohr"
Author
Contributor

Tried to amend but the force-push was sandbox-blocked. Pushed the rename as a follow-up commit instead: 5feab57b6 — switches runs-on to the full label, in build.yml + build-deb.sh comments + the -2 changelog entry. Pure label rename; no behavior change.

PR branch now: a1ff6de (sysroot) -> 051da5e (runner switch) -> 5feab57 (correct label). Squash on merge if you want a single clean commit.

Tried to amend but the force-push was sandbox-blocked. Pushed the rename as a follow-up commit instead: **5feab57b6** — switches runs-on to the full label, in build.yml + build-deb.sh comments + the -2 changelog entry. Pure label rename; no behavior change. PR branch now: a1ff6de (sysroot) -> 051da5e (runner switch) -> 5feab57 (correct label). Squash on merge if you want a single clean commit.
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marfrit/marfrit-packages#44