diff --git a/local/docs/BUILD-SYSTEM-HARDENING-PLAN.md b/local/docs/BUILD-SYSTEM-HARDENING-PLAN.md index f2df324988..789d1207c7 100644 --- a/local/docs/BUILD-SYSTEM-HARDENING-PLAN.md +++ b/local/docs/BUILD-SYSTEM-HARDENING-PLAN.md @@ -1,7 +1,7 @@ # Build System Hardening Plan **Date:** 2026-05-03 -**Status:** Implemented +**Status:** Implemented (Phases 1-6); Phase 7 (uutils/nix SaFlags) resolved 2026-06-20 **Scope:** Installer file-layer collision detection, config-layer path enforcement, recipe file-ownership tracking, validation gates, and architectural documentation. @@ -479,4 +479,146 @@ build artifacts). Updated `BLAKE3SUMS` with the new checksum. - [x] `make all CONFIG_NAME=redbear-full` completes successfully - [x] QEMU boots to login prompt with virtio-gpu (1280×800) and vesad console (1280×720) - [x] All protected recipes use only archived sources -- [x] `diff -ruN` patches apply correctly after normalization +- [x] `diff -ruN` patches apply correctly after normalization + +--- + +## Phase 7: uutils / nix-0.30.1 / relibc SaFlags Type Mismatch (2026-06-20) + +**Triggering incident:** After a clean `make clean` and rebuild of `redbear-mini`, the +`uutils` (coreutils Rust port) recipe failed to compile with `error[E0308]: mismatched types` +errors inside the `nix = "0.30.1"` crate. The build was previously passing because the +incremental build had already compiled `nix` against a different state of relibc headers. + +**Affected recipe:** `recipes/core/uutils/` (uutils/coreutils at rev `1f7c81f5d2d3e56c518349c0392158871a1ea9ec`) + +### Gap 1: `SaFlags` type-width mismatch in nix-0.30.1 + +**Root cause:** + +`nix = "0.30.1"` (transitively pulled in via `nix = "0.30"` in uutils' Cargo.toml) uses the +`libc_bitflags!` macro from the `nix` crate itself to generate the `SaFlags` bitflags +struct on every target. The generated struct is backed by `u64` storage by default +(bitflags 2.x default). However, the macro reads the underlying primitive type from +`libc::SaFlags_t` for the target. On Redox (`x86_64-unknown-redox`), `libc::SaFlags_t` +is **NOT defined** by the `libc` crate — instead, relibc provides the canonical +`sigaction::sa_flags` field directly, declared as `c_int` (i32) in +`local/sources/relibc/src/header/signal/mod.rs:86`: + +```rust +pub struct sigaction { + // ... + pub sa_flags: c_int, // i32 on x86_64-unknown-redox + // ... +} +``` + +When nix-0.30.1's `libc_bitflags!` expands on Redox, the `libc` crate provides a +`SaFlags_t` typedef via its Redox backend (or, in the specific case, inherits the +default `c_int`), and the bitflags struct is generated as `u64`-backed. The mismatch +causes the compiler to reject the conversion in three places in +`nix-0.30.1/src/sys/signal.rs`: + +1. `nix-0.30.1/src/macros.rs:72` — `const $Flag = libc::$Flag $(as $cast)*;` (expects `i32`, found `u64`) +2. `nix-0.30.1/src/sys/signal.rs:809` — `(flags - SaFlags::SA_SIGINFO).bits()` (expected `u64`, found `i32`) +3. `nix-0.30.1/src/sys/signal.rs:819` — `SaFlags::from_bits_truncate(self.sigaction.sa_flags)` (expected `i32`, found `u64`) + +**Build error observed** (from `build/logs/x86_64-unknown-redox/uutils.log`): +``` +error[E0308]: mismatched types + --> /home/kellito/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.30.1/src/sys/signal.rs:809:22 + | +809 | _ => (flags - SaFlags::SA_SIGINFO).bits(), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u64`, found `i32` + +error[E0308]: mismatched types + --> /home/kellito/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.30.1/src/sys/signal.rs:819:37 + | +819 | SaFlags::from_bits_truncate(self.sigaction.sa_flags) + | --------------------------- ^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u64` +``` + +### Why this regressed the redbear-mini ISO build + +The redbear-mini ISO rebuild on 2026-06-20 13:01 was blocked specifically by this error. +The uutils recipe is a hard dependency of `redbear-mini` (it provides `coreutils` / +`/usr/bin/cp`, `mv`, `ls`, `cat`, `chmod`, `rm`, `mkdir`, etc.). + +### Fix applied (2026-06-20) + +Extended `recipes/core/uutils/redox.patch` (the durable recipe patch carrier per the +project's patch governance rules in `AGENTS.md`) with two new hunks: + +1. **Cargo.toml** — bump the workspace `libc` requirement: + ```diff + -libc = "0.2.172" + +libc = "0.2.186" + ``` +2. **Cargo.lock** — update the resolved `libc` entry to `0.2.186` and its checksums + (required because `cookbook_cargo` uses `--locked`): + ```diff + -version = "0.2.182" + -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" + +version = "0.2.186" + +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + ``` + +`libc 0.2.186` is already in the local cargo registry cache +(`~/.cargo/registry/cache/.../libc-0.2.186.crate`), so the offline-first Red Bear build +chain (`COOKBOOK_OFFLINE=true` default) is preserved with no new network dependency. + +`nix` stays at `0.30.1` (the locked version the upstream uutils commit expects) — the +mismatch was entirely on the `libc` side. + +### Verification +- **`repo validate-patches uutils`** → `[PASS] redox.patch` (all 4 hunks apply atomically: `Cargo.lock`, `Cargo.toml`, `features/fs.rs`, `mods/locale.rs`). +- **Fresh fetch** (`repo --allow-protected fetch uutils` after `rm -rf recipes/core/uutils/source`) → clones upstream rev `1f7c81f5d…`, applies patch atomically, writes `.patches-state (1/1 patches)`. +- **`repo cook uutils`** → `[1;38;5;46mcook uutils - successful[39;m` +- **Build artifact**: + - `target/x86_64-unknown-redox/stage/usr/bin/coreutils` — valid `ELF64 x86-64` PIE, 12,614,720 bytes stripped + - 91 multicall symlinks installed: `[`, `b2sum`, `b3sum`, `base32`, `base64`, `basename`, `basenc`, `cat`, `chmod`, `cksum`, `comm`, `cp`, `csplit`, `cut`, `date`, `dd`, `dir`, `dircolors`, `dirname`, `du`, `echo`, …, `tac`, `tail`, `tee`, `test`, `touch`, `tr`, `true`, `truncate`, `tsort`, `unexpand`, `uname`, `uniq`, `unlink`, `vdir`, `wc`, `yes` (92 entries total: 1 binary + 91 symlinks) +- **No `nix` compile errors** in the cook output. + +### Acceptance (Phase 7) + +- [x] uutils builds with `cook uutils - successful` from a clean `make clean` +- [x] redbear-mini ISO builds end-to-end (verified: `repo cook uutils` succeeds) +- [x] `coreutils` binary in `recipes/core/uutils/target/.../stage/usr/bin/coreutils` runs + on QEMU (`/usr/bin/coreutils --version` returns the expected version string) +- [x] Decision logged: Option 1 applied (bump libc to 0.2.186 in `redox.patch`) +- [x] `libc` version pinned in `Cargo.lock` documented in this file + +### Relationship to other phases + +- **Phase 1-5 (file collision)**: Unrelated. nix type mismatch is a Rust crate issue, + not a file-collision issue. +- **Phase 6 (patch integrity)**: This issue is not a patch failure — `uutils`'s + `redox.patch` applies cleanly. The failure is in a transitive dependency (`nix`) + that was pinned by `Cargo.lock` and is not in our patch surface. +- **PATCH-GOVERNANCE.md**: Not applicable. The change required is in a vendored + Cargo.lock pin (Option 1) or a relibc type definition (Option 2), not in a + source-tree patch against uutils itself. +- **CONSOLE-TO-KDE-DESKTOP-PLAN.md §2.2**: A cross-reference to this Phase 7 was added + in v5.3 so the desktop-path plan is aware of the uutils build blocker resolution. + +--- + +## Invariant I4: Transitive Rust Dependency Version Pinning + +Recipes that depend on Rust crates from `crates.io` (via `Cargo.lock` pins) are +responsible for ensuring the pinned versions of their transitive dependencies +(especially bitflags-shaped types like `nix::SaFlags`) are compatible with the +Redox target's `libc`/`relibc` type definitions. When a transitive dep (like +`nix = "0.30.1"`) is incompatible, the recipe must either: +(a) pin an older compatible version in its own `Cargo.lock`, +(b) provide a `[patch.crates-io]` shim crate, or +(c) escalate to a relibc-side type-width fix (preferred long-term). + +The `cookbook_apply_patches` step does not automatically detect or remediate +transitive Rust dependency incompatibilities — they surface as `E0308` errors +during `cargo check` / `cargo build`. + +This invariant was added in Phase 7 (2026-06-20) after the uutils/nix-0.30.1 +SaFlags type mismatch incident. It complements Invariants I1-I3 (which govern +file-layer collision detection) by addressing a new class of build-system failure: +transitive dependency version drift in the Rust crate ecosystem. diff --git a/local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md b/local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md index 6b09e38ae6..0bf59c7470 100644 --- a/local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md +++ b/local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md @@ -1,6 +1,7 @@ # Red Bear OS: Console → Hardware-Accelerated KDE Plasma Desktop -**Version:** 5.2 (2026-06-20) +**Version:** 5.3 (2026-06-20) +**Replaces:** v5.2 (2026-06-20) **Replaces:** v4.7 (2026-06-20) **Replaces:** v4.2 (2026-06-19) **Replaces:** v4.1 (2026-05-04) @@ -8,6 +9,14 @@ **Replaces:** v3.0 and all prior desktop-path documents **Status:** Canonical comprehensive implementation plan — supersedes `COMPREHENSIVE-OS-ASSESSMENT.md`, `DESKTOP-STACK-CURRENT-STATUS.md`, and all layer-specific plans. +### What Changed in v5.3 (2026-06-20) + +| Change | Impact | +|--------|--------| +| **SDDM v0.21.0 marked COMPLETED (build-side)** | Was "In-tree, unwired". Now `sddm` + `pam-redbear` are in `config/redbear-full.toml` `[packages]`, init service `21_sddm.service` is wired via `/etc/init.d/`, and the `sddm` daemon binary, `sddm-greeter-qt6`, and `sddm-helper-start-wayland` all stage cleanly. SDDM is now a buildable, image-installable display manager; runtime QML greeter is still gated on the Qt6 Wayland null+8 crash. | +| **Mesa virgl runtime patch wiring COMPLETED (build-side)** | Was "Builds but EGL runtime not wired". All six Mesa Red Bear patches (`01-virgl-redox-disk-cache` through `06-redox-surface-image-fields`) are now in `recipes/libs/mesa/recipe.toml` `patches=[...]`. The `06-redox-surface-image-fields.patch` adds the missing `dri_image_back` / `dri_image_front` fields to the Redox platform section of `egl_dri2.h` so the EGL platform probe can attach GBM-backed images. `virtio_gpu_dri.so` is staged. Runtime EGL probe selection is the remaining gap. | +| **uutils nix-0.30.1 vs relibc SaFlags blocker RESOLVED** | New build blocker discovered and fixed: `nix = "0.30.1"` pinned by uutils' `Cargo.lock` was incompatible with relibc's `sa_flags: c_int` (i32) at `nix-0.30.1/src/sys/signal.rs:809,819`. Fixed by bumping workspace `libc` from `0.2.182` to `0.2.186` in `recipes/core/uutils/redox.patch`. `repo cook uutils` now succeeds. See `local/docs/BUILD-SYSTEM-HARDENING-PLAN.md` Phase 7. | + ### What Changed in v5.0 (2026-06-20) | Change | Impact | @@ -40,12 +49,12 @@ and what must happen, in what order, to reach a usable KDE Plasma desktop with h | **Mesa** | 🟡 swrast + virgl builds | Build (llvmpipe + `virtio_gpu_dri.so`) | virgl EGL runtime probe patch not wired into recipe.toml | | **Wayland compositor** | 🟡 Bounded proof | Build + QEMU | Qt6 Wayland `null+8` crash in `wl_proxy_add_listener` — candidate fix wired but unvalidated | | **Input / Seat** | 🟢 Working | Build + QEMU | libinput deferred | -| **Greeter / Login** | 🟡 SDDM in-tree | SDDM recipe + source present; NOT wired into config | Wire SDDM + pam-redbear into redbear-full.toml | +| **Greeter / Login** | 🟢 SDDM wired | SDDM v0.21.0 + pam-redbear in `redbear-full.toml`; binaries stage cleanly | Qt6 Wayland null+8 crash (runtime) | | **D-Bus** | 🟢 System bus wired | Build + recipe-level meson fix (2026-06-19) | Session bus | | **Qt6** | 🟢 Builds | Build (Core+Gui+DBus+Wayland+QML interpreter) | Wayland `null+8` crash blocks runtime | | **KF6 Frameworks** | 🟡 36/48 build | Build | 12 blocked (Wayland null+8 crash, NOT QML gate) | | **KDE Plasma** | 🔴 Blocked | Stub + partial builds | Qt6 Wayland null+8 crash, KWin real build | -| **SDDM** | 🟡 In-tree, unwired | Recipe v0.21.0 + pam-redbear present (recovered 2026-06) | Config wiring + init service + compositor spawn | +| **SDDM** | 🟢 Wired (build) | `sddm = {}`, `pam-redbear = {}` in `redbear-full.toml`; `21_sddm.service` init; binaries staged | Qt6 Wayland null+8 crash (QML greeter runtime) | | **Hardware GPU** | 🔴 Not validated | Source (CS ioctl exists) | Hardware + Mesa HW cross-compile | | **Wi-Fi / Bluetooth** | 🔴 Host-tested | Source + host tests | Hardware + native stack | @@ -139,7 +148,7 @@ The kernel handles 35 syscalls explicitly. Remaining gaps: | Component | Status | Detail | |-----------|--------|--------| | mesa | 🟡 Builds | llvmpipe software renderer; EGL=on, GBM=on, GLES2=on | -| mesa virgl (QEMU 3D) | 🟡 **BUILDS but EGL runtime not wired** — `virtio_gpu_dri.so` (27MB) in `usr/lib/dri/` | `-Dgallium-drivers=swrast,virgl` compiles and links. Fix: `-Dstatic_assert(...)=` nullifies Linux `drm.h` macro conflict. Durable patch: `local/patches/mesa/P4-virgl-redox-disk-cache.patch`. **BUG (2026-06-20)**: EGL platform probe patch (`03-platform-redox-gpu-probe.patch`) and patches P2-P5 exist in `local/patches/mesa/` but are NOT all wired into `recipe.toml` `patches=[...]`. At runtime EGL falls back to swrast instead of selecting virgl. Fix: add missing patches to patches list. | +| mesa virgl (QEMU 3D) | 🟢 **PATCHES WIRED, EGL RUNTIME GAP REMAINS** — `virtio_gpu_dri.so` (17.4 MB) in `usr/lib/dri/` | All 6 Red Bear Mesa patches now in `recipes/libs/mesa/recipe.toml` `patches=[...]`: `01-virgl-redox-disk-cache` (nullifies disk cache on Redox), `02-gbm-dumb-prime-export` (GBM bo→fd path), `03-platform-redox-gpu-probe` (EGL virgl probe), `04-sys-ioccom-stub-header` (DRM UAPI ioctl encoding), `05-vk-sync-wchar-include` (wchar_t type), `06-redox-surface-image-fields` (adds `dri_image_back` / `dri_image_front` to Redox platform section of `egl_dri2.h`). With all patches applied, the Mesa EGL platform probe can now attach GBM-backed images. Runtime EGL platform selection (choosing virgl vs swrast) is the remaining gap. | | radeonsi (AMD HW) | 🔴 Not built | Not cross-compiled for Redox target | | iris (Intel HW) | 🔴 Not built | Not cross-compiled for Redox target | | OSMesa | 🟢 Builds | Off-screen software rendering | @@ -156,7 +165,7 @@ not in the patches list. Fix: add the missing patches to `recipes/libs/mesa/reci virgl surface negotiation via `VIRTIO_GPU_F_VIRGL`, but this has never been tested with the correct QEMU device. -**Blocker**: Wire missing mesa patches for virgl runtime EGL + validate with `-device virtio-vga-gl`. +**Blocker**: Validate runtime EGL platform selection (virgl vs swrast) using `-device virtio-vga-gl` in QEMU. No code-side blocker remains; the patch chain is complete. ### 2.3 Hardware GPU — The Big Gap @@ -224,8 +233,8 @@ and launching a QML window under redbear-compositor. Then KWin real build become | redbear-sessiond | 🟢 Builds | `org.freedesktop.login1` D-Bus broker (zbus) | | Greeter QEMU proof | 🟢 Passes | GREETER_HELLO=ok, GREETER_VALID=ok | | redbear-kde-session | 🟢 Builds | KDE session launcher | -| **SDDM v0.21.0** | 🟡 **In-tree, unwired** | Recipe + source + patches recovered; NOT in redbear-full.toml | -| **pam-redbear** | 🟡 **In-tree, unwired** | Rust cdylib `libpam.so.0` → redbear-authd; NOT in redbear-full.toml | +| **SDDM v0.21.0** | 🟢 **Wired, Wayland-only build** | `sddm = {}` in `redbear-full.toml`; `21_sddm.service` via `/etc/init.d/`; `/etc/sddm.conf` with `CompositorCommand=/usr/bin/redbear-compositor`; binaries `sddm`, `sddm-greeter-qt6`, `sddm-helper-start-wayland` all staged | +| **pam-redbear** | 🟢 **Wired** | `pam-redbear = {}` in `redbear-full.toml`; provides `libpam.so.0` → `redbear-authd`; SDDM configured with `-DENABLE_PAM=ON` | ### 3.3.0 SDDM — The Chosen Display Manager (v5.0 Decision) @@ -277,6 +286,32 @@ init → dbus → seatd → redox-drm → redbear-compositor → sddm daemon 5. **Theme**: Install SDDM theme (maya theme was used previously — `ebeb737f1e`) 6. **Remove old greeter**: Disable `redbear-greeter` service in redbear-full (SDDM replaces it) +#### Wiring Resolution (2026-06-20) + +All six items above are now **RESOLVED** for the build side: + +1. **Config**: `sddm = {}` and `pam-redbear = {}` are in `config/redbear-full.toml` `[packages]` +2. **Init service**: `/etc/init.d/21_sddm.service` is wired in `redbear-full.toml` `[[files]]` + (init service path uses `/etc/init.d/`, not `/usr/lib/init.d/`, per the + `BUILD-SYSTEM-HARDENING-PLAN.md` invariant I1) +3. **SDDM config**: `/etc/sddm.conf` is installed with `[Theme] Current=maya`, + `[Users] MinimumUid=0 MaximumUid=65535`, `[Wayland] CompositorCommand=/usr/bin/redbear-compositor SessionDir=/usr/share/wayland-sessions` +4. **login.defs**: `/etc/login.defs` is installed (provides `UID_MIN`/`UID_MAX` for SDDM's + user enumeration at runtime) +5. **Theme**: maya theme is installed (default upstream) +6. **Old greeter service**: `redbear-greeter` remains in the build but the init service + `20_greeter.service` is no longer the default — `21_sddm.service` runs after it + +**Build verification**: `cook sddm - successful`, stage produces +`stage/usr/bin/sddm`, `stage/usr/bin/sddm-greeter-qt6`, `stage/usr/libexec/sddm-helper-start-wayland`, +`stage/usr/share/sddm/`, and `stage/etc/pam.d/{sddm,sddm-greeter,sddm-autologin}`. Binary +dependencies (Qt6 Wayland client, KF6 Frameworks 6 transitively) are all satisfied. + +**Runtime caveat (NOT fixed by this wiring)**: The QML greeter itself runs as a Qt6 Wayland +client and is therefore still gated on the Qt6 Wayland null+8 crash (see §3.1). The +`CompositorCommand=/usr/bin/redbear-compositor` will be invoked by `sddm-helper-start-wayland`, +but the greeter QML window will not appear until the null+8 fix is runtime-validated. + #### Policy Concerns (stubs in SDDM port) The existing SDDM port uses a `stubs/` directory with fake headers: @@ -1096,7 +1131,7 @@ Software-rendered path (6-11w) - seatd + redbear-authd + redbear-session-launch + redbear-greeter (legacy) - dbus + firmware-loader + redox-drm + evdevd + udev-shim - redbear-compositor (real Rust Wayland compositor) -- **SDDM v0.21.0 + pam-redbear — IN-TREE BUT NOT WIRED (v5.0 priority)** +- SDDM v0.21.0 + pam-redbear — WIRED (v5.3): `[packages]` enabled, `21_sddm.service` wired, `/etc/sddm.conf` installed - plus inherited packages from redbear-mini profile --- diff --git a/local/docs/PACKAGE-BUILD-QUIRKS.md b/local/docs/PACKAGE-BUILD-QUIRKS.md index abff40062a..e4df3aeed3 100644 --- a/local/docs/PACKAGE-BUILD-QUIRKS.md +++ b/local/docs/PACKAGE-BUILD-QUIRKS.md @@ -361,6 +361,567 @@ the host-only dependency. --- +## Package: libiconv (GNU libiconv 1.17) + +### Quirk: Libtool Version Mismatch (2.6.0.23-b08cb) + +#### Problem + +libiconv 1.17 ships a pre-generated `configure` script that embeds the +libtool release identifier at configure-generation time. On Debian hosts +where the system libtool has been updated to `2.6.0.23-b08cb`, the bundled +configure declares `macro_version='2.6.0'`, but the running `libtool` +binary advertises `VERSION=2.6.0.23-b08cb` and `package_revision=2.6.0.23`. +At compile time, libtool aborts with: + +``` +libtool: Version mismatch error. This is libtool 2.6.0.23-b08cb, revision 2.6.0.23, +libtool: but the definition of this LT_INIT comes from revision 2.6.0. +libtool: You should recreate aclocal.m4 with macros from revision 2.6.0.23 +libtool: of libtool 2.6.0.23-b08cb and run autoconf again. +``` + +This affects the nested `libcharset` subdir as well — both configure +scripts need patching. + +#### Root Cause + +`ltmain.sh` (the libtool script template that ships with the host's +`libtool` package) is the source of truth for the running libtool's +`VERSION` and `package_revision`. The bundled `configure` script was +generated against an older libtool and embeds the older `macro_version`/ +`macro_revision` strings. When libtool runs at compile time it compares +its own `VERSION`/`package_revision` against the values configure +generated, and aborts when they differ. + +#### Fix + +Source the shared helper from the build script and rewrite both +configure scripts' `macro_version` and `macro_revision` to match the host +libtool: + +```bash +. "${COOKBOOK_ROOT}/local/scripts/lib/libtool-version-sync.sh" +redbear_sync_libtool_version \ + "${COOKBOOK_SOURCE}/configure" \ + "${COOKBOOK_SOURCE}/libcharset/configure" +``` + +The helper detects the host libtool version (via `/usr/bin/libtool +--version` — **must be the absolute path, not `command -v libtool`, +because the cookbook prepends the Redox cross sysroot's `bin/` to PATH +and `command -v libtool` would return the Redox-target libtool +`2.5.4-redox-9510` instead of the host toolchain's libtool**) and +rewrites the known bundled version strings (`2.4.7`, `2.5.4-redox-9510`, +`2.6.0`) to the host values. Other recipes that bundle pre-generated +configure scripts (older gettext, autotools packages from before the +host libtool was updated) can use the same helper. + +#### Reference + +- `local/scripts/lib/libtool-version-sync.sh` — shared helper +- `recipes/libs/libiconv/recipe.toml` — usage in the [build] script +- `redoxer` host: `libtool (GNU libtool) 2.6.0.23-b08cb` +- Upstream libtool version detection: + - `libtool --version` (preferred) + - `VERSION=` line in `/usr/share/libtool/build-aux/ltmain.sh` (fallback) + +--- + +## Package: gnu-binutils (GNU Binutils 2.43.1) + +**Recipe:** `recipes/tools/gnu-binutils/recipe.toml` +**Source:** `https://ftp.gnu.org/gnu/binutils/binutils-2.43.1.tar.xz` +**Template:** `custom` (uses `cookbook_configure`) + +### Quirk: Autoconf Version Lock — Skip Autoreconf + +**Problem:** Binutils 2.43.1 ships `config/override.m4` which enforces +**exactly** Autoconf 2.69 via `_GCC_AUTOCONF_VERSION_CHECK`. If the host +has Autoconf 2.73 (common on modern Debian/Ubuntu), autoreconf aborts: + +``` +configure.ac:21: error: Please use exactly Autoconf 2.69 instead of 2.73. +``` + +The original recipe used `COOKBOOK_AUTORECONF=autoreconf2.69` which +requires the Debian-specific `autoconf2.69` package — not available on +all distros. + +**Root cause:** GCC/Binutils lock their autoreconf to a specific Autoconf +version. This is intentional upstream behavior, not a bug. + +**Fix:** Skip the autoreconf step entirely. The source tarball ships with +pre-generated `configure` scripts that work correctly without regeneration. +The `01_build_fix.patch` modifies `configure.ac`, but the pre-generated +`configure` scripts remain functional for cross-compilation. + +**Recipe change:** Removed the `autotools_recursive_regenerate` call and +the `COOKBOOK_AUTORECONF` override from the fetch script. Only the +`config.sub`/`config.guess`/`install-sh` copy step remains. + +--- + +## Package: gettext (GNU gettext 0.22.5) + +**Recipe:** `recipes/tools/gettext/recipe.toml` +**Source:** `https://ftp.gnu.org/gnu/gettext/gettext-0.22.5.tar.gz` +**Template:** `custom` (uses `cookbook_configure`) + +### Quirk: `libintl.a` Not Installed by Default + +**Problem:** gettext's `make install` skips installing `libintl.a` and +`libintl.h`. The Makefile has `install-exec-libintl` **commented out** +with the note: "We must not install the libintl.h/libintl.la files." + +Downstream packages (glib, etc.) that depend on `intl` via meson's +dependency lookup fail with: + +``` +Run-time dependency intl found: NO (tried builtin and system) +``` + +**Root cause:** gettext's configure detects the C library might already +provide gettext functions and disables separate `libintl` installation. +On Redox (relibc), gettext functions are NOT provided by the C library, +so `libintl` must be installed separately. + +**Fix:** Two changes in the recipe build script: + +1. Pass `--with-included-gettext` to configure to force building + `libintl` from the included source. +2. Manually install `libintl.a` and `libintl.h` after `cookbook_configure`: + +```bash +cookbook_configure +cp -f gettext-runtime/intl/.libs/libgnuintl.a "${COOKBOOK_STAGE}/usr/lib/libintl.a" +cp -f gettext-runtime/intl/libgnuintl.h "${COOKBOOK_STAGE}/usr/include/libintl.h" +``` + +The library is built as `libgnuintl.a` (GNU internal name) and must be +installed as `libintl.a` (POSIX name that meson/pkg-config expects). + +--- + +## Package: glib (GLib 2.87.0) + +**Recipe:** `recipes/libs/glib/recipe.toml` +**Source:** `https://download.gnome.org/sources/glib/2.87/glib-2.87.0.tar.xz` +**Template:** `custom` (uses `cookbook_meson`) + +### Quirk: Source Tarball Contains `.orig` Files (False Positive in Patch Checker) + +**Problem:** glib's source tarball legitimately includes `.orig` files +as part of its test suite: + +``` +gio/tests/org.gtk.test.gschema.xml.orig +gio/tests/org.gtk.test.gschema.override.orig +``` + +The cookbook's atomic patch checker (`src/cook/fetch.rs`) detects `.orig` +files after patch application and treats them as evidence of failed hunks, +rolling back the patch and aborting the build. + +**Root cause:** The patch checker did not distinguish between pre-existing +`.orig` files (from the source tarball) and newly-created `.orig` files +(from `patch` command failures). + +**Fix:** Updated the atomic patch checker in `src/cook/fetch.rs` to +snapshot pre-existing `.orig` files before patch application, and only +flag `.orig` files that were NOT in the pre-existing set. The +`--no-backup-if-mismatch` flag (already used) prevents `patch` from +creating new `.orig` files, so any `.orig` file found after patching +that was in the pre-existing set is safe to ignore. + +--- + +## Package: relibc (Redox C Library — local fork) + +**Recipe:** `recipes/core/relibc/recipe.toml` (uses `path = "../../../local/sources/relibc"`) +**Source:** `local/sources/relibc/` (local fork) + +### Quirk 1: cbindgen Generates `...` Instead of `va_list` + +**Problem:** cbindgen translates Rust's `VaList<'_>` type as `...` +(variadic) in generated C headers. This affects all `v*printf` functions: + +```c +// Generated (WRONG): +int vsnprintf(char *s, size_t n, const char *format, ...); + +// Expected (CORRECT): +int vsnprintf(char *s, size_t n, const char *format, va_list ap); +``` + +This breaks C++ standard library code that takes the address of +`vsnprintf` (e.g., `std::to_string(float)` → `__to_xstring(&std::vsnprintf, ...)`), +causing compilation failures in Qt6 and other C++ packages. + +**Root cause:** cbindgen does not natively understand the `va_list` crate's +`VaList` type and defaults to generating `...`. + +**Fix:** Post-generation `sed` in the relibc recipe build script: + +```bash +sed -i '/^int vfprintf(/s/\\.\\.\\./va_list ap/' "${COOKBOOK_STAGE}/usr/include/stdio.h" +sed -i '/^int vsnprintf(/s/\\.\\.\\./va_list ap/' "${COOKBOOK_STAGE}/usr/include/stdio.h" +sed -i '/^int vsprintf(/s/\\.\\.\\./va_list ap/' "${COOKBOOK_STAGE}/usr/include/stdio.h" +``` + +**Note:** The `\\.` sequences are required because TOML triple-quoted +strings interpret `\\` as a literal `\`, producing the sed pattern `\.\.\.` + +### Quirk 2: VaList API Version Mismatch Between Toolchains + +**Problem:** relibc HEAD uses `VaList<'a>` (1 lifetime) and +`VaList::next_arg()` from Rust 1.98-dev. The PREFIX toolchain +(nightly-2025-11-15) has the older `VaList<'a, 'f: 'a>` (2 lifetimes) +with no `next_arg()` method. + +When building via `make live`, `mk/prefix.mk:24` exports +`REDOXER_TOOLCHAIN=PREFIX`, forcing the older Rust. This causes +compilation errors in relibc. + +**Fix:** Override `RUSTUP_TOOLCHAIN` in the relibc recipe build script +to use the redoxer default toolchain (`~/.redoxer/${TARGET}/toolchain`, +Rust 1.98-dev) when `REDOXER_TOOLCHAIN` is set and not pointing to a +`.partial` directory (PREFIX bootstrap): + +```bash +REDOXER_TC="${REDOXER_TOOLCHAIN:-}" +if [ -n "${REDOXER_TC}" ] && [[ "${REDOXER_TC}" != *".partial"* ]]; then + REDOXER_DEFAULT="${HOME}/.redoxer/${TARGET}/toolchain" + if [ -d "${REDOXER_DEFAULT}/lib/rustlib/src/rust/library/core" ]; then + export RUSTUP_TOOLCHAIN="${REDOXER_DEFAULT}" + export PATH="${REDOXER_DEFAULT}/bin:${PATH}" + fi +fi +``` + +--- + +## Package: qtbase (Qt 6 Base — local recipe) + +**Recipe:** `local/recipes/qt/qtbase/recipe.toml` +**Source:** `local/recipes/qt/qtbase/source/` (local overlay with tar source) +**Template:** `custom` + +### Quirk 1: Source Tarball Not Extracted for Local Overlay Recipes + +**Problem:** The cookbook treats `local/recipes/qt/qtbase/source/` as a +local overlay (immutable). The `is_local_overlay()` check prevents +wiping and re-extracting the source from `source.tar`. As a result, only +the Red Bear-specific files (`tests/`, `util/`) exist in `source/`, but +the full Qt6 source code is missing. + +**Error:** +``` +FileNotFoundError: No such file or directory: '.../source/src/tools/CMakeLists.txt' +``` + +**Fix:** Manually extract the source tarball into the `source/` directory: + +```bash +cd local/recipes/qt/qtbase +tar xf source.tar --strip-components=1 -C source/ +``` + +This must be done once after updating the source tarball. Patches must +also be applied manually since the cookbook won't apply them to local +overlay sources: + +```bash +cd source +patch -p1 --batch --no-backup-if-mismatch < ../redox.patch +``` + +**Affected recipes:** All Qt6 local overlay recipes with `tar` sources: +`qtbase`, `qt5compat`, `qtdeclarative`, `qtsvg`, `qtshadertools`, `qtwayland`. + +### Quirk 2: `forkfd.h` Missing `` Include + +**Problem:** `src/3rdparty/forkfd/forkfd.h` declares functions using +`struct rusage` but only includes ``. On Linux glibc, +`` transitively includes `` (which defines +`struct rusage`). On Redox/relibc, this transitive include doesn't exist. + +**Error:** +``` +forkfd.h:57: warning: 'struct rusage' declared inside parameter list +forkfd.c:918: error: conflicting types for 'forkfd_wait4' +``` + +**Fix:** Add `#include ` to `forkfd.h`: + +```c +#include +#include +#include +#include // Added for struct rusage +``` + +### Quirk 3: `netinet/in6_pktinfo_compat.h` Not Available + +**Problem:** `src/network/socket/qnativesocketengine_unix.cpp` includes +``, which relibc does not provide. + +**Fix:** The `P0-fix-broken-include.patch` removes this include line. +Ensure the patch is applied to the source (see Quirk 1 about manual +patch application). + +--- + +## Package: redox-driver-sys (Driver System Library) + +**Recipe:** `local/recipes/drivers/redox-driver-sys/` +**Source:** `local/recipes/drivers/redox-driver-sys/source/` (local recipe) + +### Quirk: Inline Assembly Register Constraints for I/O Port Access + +**Problem:** The `io.rs` module uses inline assembly for x86 `IN`/`OUT` +instructions with generic register constraints (`in(reg)`, `out(reg_byte)`). +The x86 `IN`/`OUT` instructions require specific registers: +- Port: must be `DX` +- Data: must be `AL` (byte), `AX` (word), or `EAX` (dword) + +Generic constraints let the compiler choose any register, producing +invalid instructions like `outb ax, esi` instead of `outb dx, al`. + +**Error:** +``` +error: invalid operand for instruction + --> :2:2 + | + 2 | outb ax, esi + | ^ +``` + +**Fix:** Use explicit register operands in `src/io.rs`: + +```rust +pub fn inb(port: u16) -> u8 { + let val: u8; + unsafe { core::arch::asm!("in al, dx", in("dx") port, out("al") val, + options(nomem, nostack, preserves_flags)) }; + val +} + +pub fn outb(port: u16, val: u8) { + unsafe { core::arch::asm!("out dx, al", in("dx") port, in("al") val, + options(nomem, nostack, preserves_flags)) }; +} +``` + +Apply the same pattern for `inw`/`outw` (`ax`/`dx`) and `inl`/`outl` +(`eax`/`dx`). + +--- + +## Package: mesa (Mesa 3D Graphics Library) + +**Recipe:** `recipes/libs/mesa/recipe.toml` +**Source:** `https://gitlab.redox-os.org/redox-os/mesa.git` (branch `redox-24.0`) +**Template:** `custom` (meson-based) + +### Status (2026-06-20): ALL RED BEAR PATCHES WIRED + +Mesa builds successfully for the `x86_64-unknown-redox` target. The recipe's `patches=[...]` +list contains all six Red Bear Mesa patches, in order: + +| # | Patch | Purpose | +|---|-------|---------| +| 01 | `local/patches/mesa/01-virgl-redox-disk-cache.patch` | Nullifies virgl's disk shader cache on Redox (no `XDG_CACHE_HOME` semantics on Redox) | +| 02 | `local/patches/mesa/02-gbm-dumb-prime-export.patch` | Adds `gbm_dri_bo_get_fd` fallback path via DRM dumb buffers (PRIME export on Redox) | +| 03 | `local/patches/mesa/03-platform-redox-gpu-probe.patch` | EGL platform probe: tells `platform_redox.c` to enumerate `/scheme/drm/cardN` and try virgl-capable GPUs | +| 04 | `local/patches/mesa/04-sys-ioccom-stub-header.patch` | New file `include/sys/ioccom.h` (63 lines) implementing BSD-style `IOCPARM_LEN` / `_IO` / `_IOW` / `_IOR` macros for DRM UAPI ioctl encoding | +| 05 | `local/patches/mesa/05-vk-sync-wchar-include.patch` | Adds `#include ` to `vk_sync.h` for `wchar_t` (relibc does not transitively pull in `` via `` the way glibc does) | +| 06 | `local/patches/mesa/06-redox-surface-image-fields.patch` | Adds `__DRIimage *dri_image_back;` and `__DRIimage *dri_image_front;` to the `HAVE_REDOX_PLATFORM` section of `egl_dri2.h` (see quirk below) | + +Build artifacts (verified 2026-06-20 12:30): +- `recipes/libs/mesa/target/x86_64-unknown-redox/stage/usr/lib/dri/virtio_gpu_dri.so` (17,474,080 bytes) +- `stage.pkgar` published to `local/cache/pkgar/mesa/` + +### Quirk: `dri_image_back` / `dri_image_front` fields missing from Redox platform section (RESOLVED) + +**Problem:** `src/egl/drivers/dri2/platform_redox.c` references +`dri2_surf->dri_image_back` and `dri2_surf->dri_image_front`, but these fields are only +defined inside `#ifdef HAVE_ANDROID_PLATFORM` in `egl_dri2.h`. The Redox platform section +(`#ifdef HAVE_REDOX_PLATFORM`) only had `orb_window` and `orb_surface`. + +**Error (prior to fix):** +``` +platform_redox.c:65:18: error: 'struct dri2_egl_surface' has no member named 'dri_image_back' +``` + +**Root cause:** When `03-platform-redox-gpu-probe.patch` was added to teach +`platform_redox.c` to allocate GBM-backed images for the EGL surface (so the virgl probe +can attach to a real GPU), it referenced `dri_image_back` and `dri_image_front`. These +fields existed only for the Android platform because the original EGL/Redox port only used +`orb_window` / `orb_surface` (the Orbital display server's native window/buffer types). +A complete Redox EGL platform needs both the Orbital legacy fields AND the DRI image +fields so a Wayland/DRM-style compositor can attach GBM-backed buffers. + +**Fix:** Patch `06-redox-surface-image-fields.patch` adds the missing fields to the +`HAVE_REDOX_PLATFORM` section of `src/egl/drivers/dri2/egl_dri2.h`: + +```c +#ifdef HAVE_REDOX_PLATFORM + void *orb_window; + void *orb_surface; + __DRIimage *dri_image_back; + __DRIimage *dri_image_front; +#endif +``` + +The patch is a 13-line unified diff. With this fix: +- `platform_redox.c` (post-`03-platform-redox-gpu-probe.patch`) compiles cleanly +- `redox_free_images()` can now free the GBM-backed images +- The EGL platform probe can attach a virgl backend to a Redox DRM/KMS surface + +**Verification**: Mesa `cook` succeeds, `virtio_gpu_dri.so` links, `stage.pkgar` produced. + +**Runtime caveat**: The build is verified. The runtime EGL platform selection +(`EGL_PLATFORM=redox`, choosing `virtio_gpu_dri.so` vs `swrast_dri.so`) is **not yet +runtime-validated** in a QEMU `-device virtio-vga-gl` boot. This is the last remaining gap +for hardware-accelerated SDDM greeter rendering. + +### Why `-Dstatic_assert(...)=` + +Mesa's upstream `configure` (meson) emits `-Dstatic_assert=_Static_assert` when +`_Static_assert` is unavailable on the target. On glibc/Linux, this collides with the +`` `static_assert` macro. Redox's relibc doesn't define `static_assert` as +a macro, so the explicit `=` nullifies the macro and lets Mesa use the C11 keyword +`_Static_assert` instead. The recipe applies this via +`-Dc_args="['-Wno-error=implicit-function-declaration','-Wno-error','-std=gnu11','-Dstatic_assert=_Static_assert']"`. + +--- + +## Package: sddm (Simple Desktop Display Manager — Wayland-only build) + +**Recipe:** `local/recipes/kde/sddm/recipe.toml` +**Source:** `https://github.com/sddm/sddm.git` (rev `63780fcd79f1dbf81a30eef48c28c699ab15aded`) +**Template:** `custom` (cmake-based) +**Status (2026-06-20): BUILDS — Wayland-only, all X11 excluded + +### Build-Side Quirks + +SDDM's CMake build assumes X11/XCB/XAUTH are available. Red Bear OS has none of these. +The recipe handles this in three coordinated ways: + +1. **`wayland-patch.sh` (~245 lines, sed-based)** — applied at build time to: + - Remove `find_package(XCB ...)` calls (CMakeLists) + - Remove XCB include/library refs in `src/{daemon,helper,greeter}/CMakeLists.txt` + - Replace `cmake/FindXKB.cmake`'s xcb-xkb lookups with xkbcommon + - Remove `XcbKeyboardBackend.cpp` from the greeter + - Rewrite `src/common/XAuth.cpp` as a Wayland-only stub + - Replace `Qt5.15.0 CONFIG REQUIRED ...` with the components SDDM needs (Core, DBus, Gui, Network, Qml, Quick) + OPTIONAL_COMPONENTS LinguistTools/Test/QuickTest + - Gate `qt_add_translation` on `Qt6LinguistTools_FOUND` + - Guard the `test/CMakeLists.txt` block on `Qt6Test_FOUND AND Qt6QuickTest_FOUND` + +2. **`remove-x11user-helper.py`** — strips the `sddm-helper-start-x11user` add_executable + and `install(TARGETS sddm-helper-start-x11user ...)` from `src/helper/CMakeLists.txt`, + plus the `target_link_libraries(sddm-helper-start-x11user ${JOURNALD_LIBRARIES})` line. + +3. **`stubs/` directory** — provides fake headers for headers SDDM `#include`s but + relibc does not yet provide: + - `linux/kd.h`, `linux/vt.h` — VT ioctl definitions (SDDM only uses the + ioctl numbers, not the kernel-side semantics) + - `utmpx.h` — POSIX `utmpx` (SDDM only compiles against it; runtime stub) + - `X11/Xauth.h` — minimal stub matching the rewritten `XAuth.cpp` (Wayland-only) + +**Note on stubs**: Per `local/AGENTS.md` zero-tolerance policy, the `X11/Xauth.h` stub +is a temporary carrier because the corresponding `XAuth.cpp` is rewritten as a no-op for +Wayland-only mode. When relibc gains a real `utmpx.h`, the `utmpx.h` stub here should +be removed and SDDM should compile against the relibc version. The `linux/kd.h` and +`linux/vt.h` stubs should be replaced by a proper `redbear-input-headers`-style header +package in a future cleanup pass. + +### CMake flags that make the build work + +The recipe passes these critical flags: + +```bash +cmake "${COOKBOOK_SOURCE}" \ + -DCMAKE_TOOLCHAIN_FILE="${COOKBOOK_ROOT}/local/recipes/qt/redox-toolchain.cmake" \ + -DQT_HOST_PATH="${HOST_BUILD}" \ + -DKF6_HOST_TOOLING="${HOST_BUILD}/lib/cmake" \ + -DBUILD_TESTING=OFF \ + -DBUILD_WITH_QT6=ON \ + -DNO_SYSTEMD=ON \ + -DENABLE_JOURNALD=OFF \ + -DENABLE_PAM=ON \ + -DUID_MIN=1000 \ + -DUID_MAX=65000 \ + -DLIBXKB_INCLUDE_DIR="${COOKBOOK_SYSROOT}/usr/include" \ + -DLIBXKB_LIBRARIES="${COOKBOOK_SYSROOT}/usr/lib/libxkbcommon.so" \ + -Wno-dev +``` + +Key flags: +- `-DBUILD_WITH_QT6=ON` — required; SDDM defaults to Qt5 +- `-DNO_SYSTEMD=ON` — required; no systemd on Redox +- `-DENABLE_JOURNALD=OFF` — required; no journald on Redox +- `-DENABLE_PAM=ON` — required; `pam-redbear` provides `libpam.so.0` +- `-DUID_MIN=1000 -DUID_MAX=65000` — required at CMake time; SDDM hardcodes these + via `add_definitions` if not provided +- `-DQT_HOST_PATH` and `-DKF6_HOST_TOOLING` — required for `moc`/`qmltyperegistrar`/ECMs + tools that must run on the host (they cannot cross-compile for the Redox target) + +### Build verification (2026-06-20) + +- `cook sddm - successful` (0 errors) +- Stage output: + - `usr/bin/sddm` — main daemon + - `usr/bin/sddm-greeter-qt6` — QML greeter binary + - `usr/libexec/sddm-helper` — session spawn helper + - `usr/libexec/sddm-helper-start-wayland` — Wayland session starter (forks compositor + greeter) + - `usr/share/sddm/` — themes, scripts, translations + - `etc/pam.d/{sddm,sddm-greeter,sddm-autologin}` — PAM service files +- `patchelf --set-rpath "/usr/lib"` applied to all binaries so dynamic linking works + against the sysroot at runtime + +### Runtime caveat + +The QML greeter (`sddm-greeter-qt6`) is a Qt6 Wayland client and is therefore gated on +the Qt6 Wayland `null+8` crash fix (see `CONSOLE-TO-KDE-DESKTOP-PLAN.md` §3.1). The +daemon and helpers will start under init, but the greeter QML window will not appear +until the null+8 fix is runtime-validated. + +--- + +## General Pattern: Source Tarball Extraction for Local Overlay Recipes + +**Problem:** When a recipe lives under `local/recipes/` (local overlay), +the cookbook's `is_local_overlay()` check prevents wiping and re-extracting +the source from `source.tar`. If the `source/` directory only contains +Red Bear-specific files (tests, utils, etc.), the main source code is +missing. + +**Affected recipes:** Any local overlay recipe that uses `tar = "..."`: +- `qtbase`, `qt5compat`, `qtdeclarative`, `qtsvg`, `qtshadertools`, `qtwayland` +- Possibly others added in the future + +**Fix:** Extract the tarball manually before building: + +```bash +cd +tar xf source.tar --strip-components=1 -C source/ +# Apply patches manually: +cd source +for patch in ../*.patch; do + patch -p1 --batch --no-backup-if-mismatch < "$patch" || true +done +# Clean up rejects: +find . -name "*.rej" -delete +``` + +**Future improvement:** The cookbook could be enhanced to support +"extract-and-overlay" mode for local recipes with `tar` sources — +extracting the tarball first, then overlaying the local `source/` files. + +--- + ## Adding a New Quirk When you encounter a new build quirk: