Repository navigation
Linux2026 - Updates for arm64 / Raspberry Pi - #8540
Conversation
f240cd9 to
78062f7
Compare
Test run: Ubuntu 26.04 LTS, aarch64 (Parallels VM, Wayland, virgl GL 4.0 / Mesa 26.0.3)Tested at
Notes:
|
RPi CI failure: apothecary GLFW built without X11/WaylandBoth CauseChecked the
In apothecary if [[ "$PLATFORM" =~ ^arm64$ ]] && [ "$TYPE" = "linux" ]; then
GLFW_WAYLAND=1; GLFW_X11=1
else # <- aarch64, armv6l, armv7l all land here
DEFINES="$DEFINES -DGLFW_USE_EGL=1 -DGLFW_CLIENT_LIBRARY=glesv2"
GLFW_WAYLAND=0; GLFW_X11=0
fiThe RPi workflow ( Proposed fix (apothecary)Build all Linux ARM targets with X11 and Wayland on. GLFW 3.4 still creates EGL/GLES contexts on either backend: if [[ "$PLATFORM" =~ ^(arm64|aarch64|armv6l|armv7l|armv8)$ ]]; then
export GLFW_WAYLAND=1
export GLFW_X11=1
elseThen rebuild the RPi A stopgap would be to guard the X11/Wayland/GLX native calls in |
|
Apothecary fixed for raspberry Pi GLFW builds now. This is looking good. |
|
== source contracts == == MSYS2 ABI library paths expand without recursion == == find_platform_lib_path (new wins, old is fallback) == == PLATFORM_LEGACY_LIB_SUBPATHS aliases in config.shared.mk == Passed: 30 Failed: 0 |
e7d9652 to
f692c74
Compare
Third-party addons with old (pre-0.13) library paths: tested on
|
| Check | Result |
|---|---|
| tjCompress to file (q90) | PASS, 13237 bytes |
| tjDecompress from file | PASS, 320x240 |
| Round trip vs original | PASS, mean error 0.75 / 255 |
| Memory buffer round trip | PASS, identical to file decode |
| FreeImage decodes the TurboJPEG file | PASS, diff 0.96 vs TurboJPEG decode |
Note, not a linux2026 issue: the addon bundles a static libjpeg (API v62), and the executable exports its jpeg_* symbols over the system libjpeg.so.8 (v80) that libfreeimage uses. Without a workaround, ofImage::load() of any JPEG then fails inside the same app ("Wrong JPEG library version: library is 62, caller expects 80"). Adding PROJECT_LDFLAGS = -Wl,--exclude-libs,libjpeg.a:libturbojpeg.a to the project's config.make fixes it, and that's what the run above uses. The same thing would happen on master with this addon.
ofxLibwebsockets (robotconscience/ofxLibwebsockets @ f29422e)
- libwebsockets 1.4 (
v1.4-chrome43-firefox-36, the version the addon's headers expect) built static for arm64 with OpenSSL, intolibs/libwebsockets/lib/linuxarm64/ - Link line picks up
…/libwebsockets/lib/linuxarm64/libwebsockets.aplus system-lssl -lcrypto -lz. The addon's x86_64linux64lib and the armv6l/armv7l libs are correctly skipped.
| Check | Result |
|---|---|
Server::setup() on port 9095 |
PASS |
Client::connect() to ws://localhost:9095 |
PASS |
| 5 messages client → server → echo → client | PASS, 5/5 matched |
Screenshots
Screenshots of both test apps to follow.
|
After extensive tests. @ofTheo what do you think I can do another pass with screenshots but I this this solves most problems with make and paths even using the new paths for libraries but supporting the old too |
Raspberry Pi OS (Trixie) Docker test results + downloader fixRan the Results
Finding 1 (fixed in 1d0f764, pushed to this branch)Inside genuine RPi OS Trixie userland, nothing detected a Raspberry Pi: Fix: Environment notes (not code bugs)
Full logs: |
|
Test harness used for the Raspberry Pi OS (Trixie) results above is now published: https://github.com/danoli3/ofLinuxTestScripts Run with: |
|
Running Popular Distros 2026 linux tests now |
2026 distro matrix — interim results (successes so far)Added one-click (
Findings
Fixes pushed to the harness ( |
Detect Raspberry Pi so aarch64 stays the Pi 64-bit package, not generic arm64. Request the GCC 10 baseline for all official Linux targets, extract archives as-is, and keep lib/linux/<arch> instead of flattening back to linux64/linuxarmv6l.
OF_DIR was unset so compileOF/PG/examples resolved the repo root wrong. compileOF now maps 64/arm64/aarch64/armv6l/armv7l/jetson to lib/linux/<arch>. RPi CI looks at scripts/ci/linux/rpi/raspbian.
scripts/ci/linux/rpi is one directory deeper than the old linuxrpi path, so OF_ROOT resolved to scripts/ and the armv7l template copy failed. Walk up four levels. Do not cancel sibling RPi slices on one failure.
CI is not a Pi, so RPI_DETECTED is no and armv6l/armv7l fell through
to a tab-prefixed $(error) ("recipe commences before first target").
aarch64 was remapped to generic arm64 and looked in lib/linux/arm64.
Treat armv6l/armv7l/aarch64, RPI_DETECTED, and RPI_ROOT as RPi so
libs resolve under lib/linux/<arch>. Keep generic ARM desktop on
linux/arm64. Resolve third-party and addon libs via canonical then
legacy subpaths. Official Linux archives are GCC 10 only.
Skip the RPi example build until latest includes glm/tess2. Drop the
22.04 apt cache that used 24.04 package names.
Run a dedicated workflow on push and pull_request that extracts find_platform_lib_path and checks each official arch: new nested folder wins, pre-0.13 flat folder still resolves, missing stays empty.
linux/64/run_tests.sh copied a host Makefile into every tests/* folder and executed the binary. android / emscripten / ios / tvOS are not headless Linux unit tests (GLFW needs DISPLAY). Use the linux64 templates to match build.sh.
Latest msys2 clang64/mingw64/ucrt64 packages embed both a GNU and an MSVC symbol index in kiss/tess2/videoInput .a files. MinGW ld then treats the archive as a linker script; lld reports unknown file type. Rebuild those archives with ar/ranlib after extract. Prefer lib/msys2/x86_64 when apothecary nests an arch folder.
Add scripts/ci/check_deployed_libs.sh and run it after download_libs on linux, RPi, and msys2. Fail if tess2/kiss/zlib (or msys2 videoInput) are missing or not GNU ar. RPi still allows the zlib-only smoke-test archive. The Linux lib-paths workflow also downloads linux_64 and checks real files.
reindexMsys2StaticLibs extracted each archive with "ar x" into one
directory and repacked it with "ar rcs". Same-named members overwrite
each other on extraction, so the repacked libopencv_world.a lost 17 of
its 512 objects (13 duplicate names, incl. core/src/parallel.cpp.o and
core/src/tables.cpp.o) and the msys2 allAddonsExample link failed with
undefined cv::parallel_for_ / cv::g_Saturate8u - even though the
apothecary package itself is correct.
Archives with duplicate member names now only get their symbol index
rebuilt in place ("ar s" + ranlib), as apothecary does since openframeworks#606.
Raspberry Pi OS Bookworm/Trixie reports ID=debian in /etc/os-release and containers expose no device-tree, so is_raspberry_pi() and the makefile RPI_DETECTED both missed genuine RPi OS userlands. The downloader then fetched the generic linux/arm64 artifact (or kept an explicit -a arm64) while builds expected linux/aarch64, failing to link tess2/kiss. Accept /etc/rpi-issue and the Raspberry Pi apt repository (archive.raspberrypi.org/.com) as Pi markers in both places, normalise an explicit -a arm64 to aarch64 when a Pi is detected, and cover the detection with fixtures in scripts/ci/linux/test_lib_paths.sh (35 tests). Verified in n4jm4/raspberry-pi-os:trixie (arm64): detection now fires, core builds to lib/linux/aarch64 and tests/addons/networkTcp links.
Linux excluded the bundled FreeImage (PLATFORM_CORE_EXCLUSIONS FreeImage/%) and linked the system library, but Arch-based distros dropped freeimage to the AUR, so core stopped at FreeImage.h missing (CachyOS/Omarchy harness runs; apothecary#674). Use the apothecary copy (header + FreeImage.a, auto-collected like tess2/kiss) on all Linux: drop the exclusion and the -lfreeimage link. Covered by scripts/ci/linux/test_lib_paths.sh (37 tests); verified in the RPi OS arm64 container where imageFormats now compiles with -I libs/FreeImage/include and links.
L4T containers expose no device-tree, so Jetson detection could never fire there and the linux/jetson apothecary path was unreachable in Docker-based testing. ?= keeps the device-tree probe by default while letting CI/containers pass JETSON_DETECTED=yes explicitly.
Apothecary publishes no linux_jetson archive (the asset 404s), and L4T is Ubuntu arm64, so map Jetson to the generic arm64 package in download_libs (explicit -a jetson/armv8l and Tegra/nv_tegra_release detection) and point the makefile Jetson lib path at linux/arm64. Covered by test_lib_paths.sh (40 tests).
Test matrix: platforms and distros testedEverything run against this PR so far, in one table. ✅ means it passed. Each row says which commit it was tested on: CI (GitHub Actions)
Linux distros: full run"Full" means: download libs, check the deployed libs, build the OF core, and run the unit tests. These ran on
Current head
|
| Check | Result |
|---|---|
scripts/dev/tests/test-download-validation.sh (#8591's tests with this branch's download_libs.sh), Bash 3.2 |
✅ |
scripts/linux/download_libs.sh on Ubuntu 24.04 x86_64 (Docker) |
✅ openFrameworksLibs_latest_linux_64_gcc10 deployed to lib/linux/64 |
Old (pre-0.13) addon library paths
Tested on 61fdd4489, Ubuntu 26.04 aarch64. The addons were unmodified upstream clones, with their libs in the old flat lib/linuxarm64/ folder, so they were found through the linux/arm64 → linuxarm64 / linuxaarch64 fallback.
| Addon | Result |
|---|---|
| ofxTurboJpeg | ✅ compress / decompress / round trip, memory buffers, FreeImage cross-check |
| ofxLibwebsockets | ✅ server + client on localhost, 5/5 echoed messages |
Fixes that came out of this testing (on this branch)
1d0f764c0Raspberry Pi OS userland detection, so Pis get theaarch64libs.9704d872b,3dc5f1f17Linux uses apothecary's FreeImage (Arch droppedfreeimageto the AUR; Linux (Arch/CachyOS): core build fails - system FreeImage gone (AUR-only), bundled apothecary copy excluded by OF makefiles apothecary#674).6424d1042,029798f03Jetson detection, and the Ubuntu arm64 libs for L4T.
Not covered / known
- Real ARMv6 hardware (Pi Zero / Pi 1): only the CI cross-build, not run on a device.
- Fedora / openSUSE: not run yet.
- Environment-only failures, not OF bugs:
utils/stringsneeds a UTF-8 locale. Fixed separately in ofToLower / ofToUpper: use a UTF-8 locale when the environment has none #8593, and the workflows setLC_ALL=C.UTF-8.utils/fileUtilspermission fixtures fail only on virtiofs mounts (91/91 on a native filesystem).
- One side effect: after
download_libs, the trackedlibs/openFrameworksCompiled/lib/{linux64,linuxarmv6l,linuxarmv7l}/.gitkeepfiles show as deleted ingit status(the old flat folders are moved to the new layout).
|
All tests complete! Lets get this in and make plans for 12.2 |
Linux 2026
Draft for the makefile / download path split that matches current apothecary Linux artifacts.
Companion: openframeworks/apothecary#585 (Raspberry Pi aarch64 / armv7l / armv6l QEMU + GCC 10, all platforms green).
Lib paths (makefile + apothecary)
ARCH64lib/linux/64arm64lib/linux/arm64aarch64lib/linux/aarch64armv7llib/linux/armv7larmv6llib/linux/armv6lLegacy flat folders (
linux64,linuxarmv6l, …) stay as addon fallbacks.Official archives (GCC 10 baseline)
openFrameworksLibs_<tag>_linux_<ARCH>_gcc10.tar.bz2download_libs.shnow:aarch64(does not pull genericlinux_arm64)_gcc10for the five official Linux targets--strip-components=1)lib/linux/<arch>Status
master(2026-10-10): no merge commits; apothecary submodule at master'saac2679(Linux modular library builds, xcode projects are gone from master branch? #593)