Commit Graph

2733 Commits

Author SHA1 Message Date
vasilito 9bb2de2c14 docs(matrix): annotate MS-7D70 availability (compile-only baseline) 2026-08-05 02:42:24 +03:00
vasilito 5d283452ec feat(scripts): Rust X670E host evidence capture kit + initial artifacts 2026-08-05 02:42:22 +03:00
vasilito 27f4c1e1dc feat(quirks): add MS-7D70 (X670E CARBON WIFI) DMI profile 2026-08-05 02:42:18 +03:00
vasilito c06e51c496 docs(plan): add Ryzen 7000 / X670E host compatibility plan 2026-08-05 02:42:16 +03:00
vasilito 1cbbc66fa4 quirks: add MSI MPG X670E CARBON WIFI (MS-7D70) DMI anchor + loader test
Pre-existing uncommitted first-party work, surfaced by the first-party
integrity gate. Committing rather than reverting: this code exists nowhere but
this project, so a revert would destroy it outright, and it is coherent and
self-consistent -- a DMI entry for the board plus a test in toml_loader.rs that
parses the REAL 50-system.toml and asserts the entry matches while LG entries
do not.

The quirk carries no flags by design; its comment states it is a bare-metal
anchor so future board-specific quirks can be added precisely. Related to the
Ryzen 7000 / X670E work in .omo/plans/ryzen-7000-x670e-compat.md.

Not authored in this session -- committed here because it blocked every build
and the gate's guidance is to commit or revert, and reverting irreplaceable
work is the wrong call.
2026-08-05 02:33:36 +03:00
vasilito 15d67086c8 plasma-desktop: overlay host build-time generators
plasma-desktop cleared configure and failed in the build:
  /bin/sh: .../sysroot/lib/libexec/kf6/kconfig_compiler_kf6: cannot execute
KF6 exports these generators as imported targets whose IMPORTED_LOCATION is the
TARGET (Redox) binary in the sysroot, so cmake tries to run a Redox ELF on the
build host.

Overlays the HOST binary onto the path the imported target points at. Their
output is plain text/XML, so a host build is equivalent, and this keeps the
features ENABLED rather than switching them off. Same block plasma-workspace
already carries -- verified /usr/lib/kf6/kconfig_compiler_kf6 exists on this
host before relying on it.
2026-08-05 02:30:48 +03:00
vasilito bf05bf1123 x11: promote libxkbfile; clear build dirs stranded by the wip move
kcms/keyboard links X11::xkbfile (CMakeLists.txt:37) and cmake aborted with
"Target kded_keyboard links to X11::xkbfile but the target was not found".
libxkbfile was sitting in recipes/wip/x11; promoted, given its util-macros
dependency, and wired into plasma-desktop and the config.

Also clears 9 build directories stranded by the earlier `git mv` out of wip.
Autotools bakes the absolute srcdir into its generated Makefiles, so a moved
recipe keeps building against a path that no longer exists:
  No rule to make target
  '.../recipes/wip/x11/libxkbfile/source/src/cout.c', needed by 'cout.lo'
The cook-side auto-invalidation added earlier only inspects CMakeCache.txt, so
autotools recipes are not covered by it -- these were latent failures that
would have surfaced one package at a time (libx11, libxcb, libxdmcp, libxft,
libxrender, x11proto, x11proto-kb, xcb-proto, xtrans).

Verified: cook libxkbfile - successful, libxkbfile.a staged.
2026-08-05 02:24:19 +03:00
vasilito ebb1dd8acb plasma-desktop: depend on the X11 libraries; disable doc generation
feature_summary aborted on two REQUIRED packages:

 * X11 -- "Required for building the X11 based workspace". The libraries exist
   (promoted out of wip and building), but plasma-desktop did not depend on
   them, so they were absent from its sysroot and cmake reported X11 missing.
   Exactly the gap libxcb had earlier. Added libx11, libxext, libxfixes, libxi,
   libxrender, libxau, libxdmcp.

   This is where providing the real X11 stack pays off: the alternative was
   patching plasma-desktop to stop requiring X11 at all, which is a much larger
   and more invasive change than declaring a dependency that already builds.

 * KF6DocTools -- not ported, and REQUIRED only because BUILD_DOC defaults ON.
   Disabled: this drops generated handbook pages, not functionality; every
   settings module still builds.
2026-08-05 02:15:43 +03:00
vasilito 619d0ec5c3 plasma-desktop: disable the X11-session touchpad backend too
kcms/touchpad/CMakeLists.txt:18 carries the identical FATAL_ERROR to
kcms/mouse, on the same missing xorg-libinput (the X SERVER input driver, not
portable to a system with no X server). Disabled pre-emptively rather than
after another ~15-minute cycle rediscovers it.

Both KCMs keep their KWin+Wayland backends -- BUILD_KCM_MOUSE_KWIN_WAYLAND and
BUILD_KCM_TOUCHPAD_KWIN_WAYLAND remain ON -- so neither module is lost, only
its unusable X11-session path.
2026-08-05 02:09:05 +03:00
vasilito b7e20cf813 plasma-desktop: disable the X11-session mouse backend
kcms/mouse/CMakeLists.txt:4 gates an X11-specific backend on xorg-libinput,
X11_Xi and X11_Xinput, and aborts naming the remedy:
  Missing X11 dependencies for kcm_mouse: xorg-libinput;X11_Xi;X11_Xinput.
  Install dependencies or set CMake option -DBUILD_KCM_MOUSE_X11=OFF.

xorg-libinput is the X SERVER input driver -- there is no X server here, so it
is not a porting candidate. This drops only the X11-session backend; the mouse
KCM still builds with its Wayland/libinput backend, which is the one actually
used.
2026-08-05 02:06:29 +03:00
vasilito b8a9e0280b plasma-desktop: split the cmake-include sed into two commands
The single sed with an embedded \n had to survive TOML unescaping, then the
shell, then sed's insert parsing -- and it did not. The generated file began
with 'nclude(CheckIncludeFiles)', losing the leading 'i', so configure failed
with
  ConfigureChecks.cmake:2 (nclude): Unknown CMake command

My earlier dry-run passed because I ran the sed by hand in the shell rather
than the form the recipe actually produces after parsing. Verified this time by
extracting the commands from the PARSED TOML and running those: the file now
starts with include(CheckFunctionExists) / include(CheckIncludeFiles).
2026-08-05 01:59:56 +03:00
vasilito efa29a3207 plasma-desktop: include CheckFunctionExists/CheckIncludeFiles
ConfigureChecks.cmake calls check_function_exists() and check_include_files()
without including the modules that define them:
  ConfigureChecks.cmake:14: Unknown CMake command "check_function_exists"
Upstream gets away with it because a native KDE configure has already pulled
those modules in transitively by that point; that does not happen here. CMake
documents both as requiring an explicit include(), so adding them is what
upstream should have done rather than a workaround.
2026-08-05 01:53:24 +03:00
vasilito 0bc52b5c1f plasma-desktop: accept a sysroot-prefixed XKBDIR when cross-compiling
ConfigureChecks.cmake:7 does
    pkg_get_variable(XKBDIR xkeyboard-config xkb_base)
    if (NOT EXISTS "${CMAKE_SYSROOT}/${XKBDIR}")
assuming pkg-config returns an unprefixed path. This build sets
PKG_CONFIG_SYSROOT_DIR, so pkg-config already applies the sysroot and XKBDIR
comes back absolute. Prefixing again produced
  .../sysroot//mnt/data/.../sysroot/usr/share/X11/xkb
and configure aborted although the directory is present (verified: the xkb
directory IS in plasma-desktop's sysroot, and xkeyboard-config.pc correctly
records xkb_base=/usr/share/X11/xkb).

Accepts either form instead of un-prefixing XKBDIR: which one pkg-config
returns depends on PKG_CONFIG_SYSROOT_DIR, so testing both is correct in both
configurations and keeps the check meaningful rather than disabling it.
2026-08-05 01:46:54 +03:00
vasilito f87a26de38 libxkbcommon: enable xkbregistry for plasma-desktop
plasma-desktop requires it unconditionally:
  CMakeLists.txt:244  pkg_check_modules(XKBREGISTRY xkbregistry REQUIRED ...)
and configure aborted with "The following required packages were not found:
- xkbregistry". The recipe had -Denable-xkbregistry=false.

xkbregistry provides the keyboard-layout registry the keyboard KCM reads, so
this restores a real feature rather than routing around one. Its dependency,
libxml2, was already in the tree (recipes/libs/libxml2) and is now declared and
added to the config.

-Denable-x11 is deliberately left false for now: it is a separate switch, not
required by this failure, and turning it on alongside would blur which change
fixed what if the rebuild misbehaves.
2026-08-05 01:08:16 +03:00
vasilito c96431e44b cook: document why staged-source diffs must not reset the build dir
I tried resetting the build dir whenever rsync reported changed files, to catch
stale GENERATED build files after a recipe edit -- the xcb-util-image case where
the staged source said `SUBDIRS = image` but build/Makefile still said
`SUBDIRS = image test`, so a correct fix looked like it had no effect.

That signal is wrong. --delete restores the pristine tree, undoing the previous
build's seds, so rsync reports changes on EVERY run. Measured on a plain
kirigami rebuild: 6 "changed" files that were only the sed undo, and the build
dir was wiped. Shipping it would have forced a full rebuild of every recipe on
every build.

Reverted, with the reasoning recorded at the call site so it is not attempted
again. Stale generated files are the job of the content-hash invalidation the
cookbook already performs against the PRISTINE source; the staged copy is not a
valid basis for that comparison.

Verified after revert: kirigami is cached again rather than rebuilding.
2026-08-05 00:56:35 +03:00
vasilito ab9ccae80f xcb-util-image: build for Redox; search recipe sysroot for autoconf macros
Three separate defects, one per class:

1. script.rs passed autoreconf only -I${COOKBOOK_HOST_SYSROOT}/share/aclocal, so
   macros installed by a DEPENDENCY into the per-recipe sysroot were invisible.
   util-macros was built and declared as a dependency, yet configure still said
     configure.ac:10: error: must install xorg-macros 1.16.0 or later
   Now also searches ${COOKBOOK_SYSROOT}/usr/share/aclocal and exports
   ACLOCAL_PATH. Fixed generically -- every autotools recipe benefits.

2. Upstream builds test/test_xcb_image_shm unconditionally (Makefile.am:15
   SUBDIRS = image test) and it needs SysV shared memory, which Redox lacks.
   The library itself does not: configure only probes sys/shm.h and adapts. So
   dropping test/ removes a test binary, not functionality.

3. libxcb is a STATIC archive here, so its libXau/libXdmcp dependencies do not
   propagate to consumers as a shared library's DT_NEEDED would:
     xcb_auth.c: undefined reference to `XauGetBestAuthByAddr'
   Named them via LIBS, not LDFLAGS: autoconf emits LDFLAGS BEFORE the objects
   and LIBS AFTER, and a static archive only satisfies symbols referenced by
   objects preceding it. With -lXau in LDFLAGS the link still failed while
   libXau.a sat in the sysroot. Same ordering rule as -lgcc in
   redox-toolchain.cmake and -licudata in plasma-workspace -- third occurrence.

Verified: cook xcb-util-image - successful, libxcb-image.a staged.
2026-08-05 00:52:14 +03:00
vasilito a55e1d6bd9 x11: add util-macros; xcb-util needs it to autoreconf
xcb-util and xcb-util-image start configure.ac with XORG_MACROS_VERSION(), so
autoreconf dies before configure runs:
  configure.ac:10: error: must install xorg-macros 1.16.0 or later before
  running autoconf/autogen
libice failed identically earlier -- it was dropped as unnecessary, but
xcb-util-image is genuinely required (plasma-desktop needs the XCB IMAGE
component), so the macros had to be ported rather than routed around.

util-macros ships only autoconf m4 text and a pkg-config file -- no compiled
code, so no cross-compilation concern. Installed into the sysroot's
share/aclocal, which is already the directory the cookbook passes to
autoreconf (-I .../sysroot//share/aclocal), so consumers need no other change.

Verified by cooking it standalone before wiring it in: builds successfully and
stages usr/share/aclocal/xorg-macros.m4. The recipe asserts that file exists,
since a silent no-op would resurface as the same "must install xorg-macros"
error in a consumer, far from the cause.
2026-08-04 23:30:09 +03:00
vasilito 68b3916eb1 plasma-desktop: provide XCB with SHM and IMAGE components
plasma-desktop's CMakeLists.txt:223 does
  find_package(XCB REQUIRED COMPONENTS XCB SHM IMAGE)
and configure aborted with "Could NOT find XCB (missing: XCB_LIBRARIES XCB SHM
IMAGE)" -- libxcb was promoted but plasma-desktop did not depend on it, so it
was absent from that recipe's sysroot.

libxcb supplies xcb and xcb-shm (libxcb-shm.a confirmed staged); IMAGE comes
from xcb-util-image, which needs xcb-util. Both promoted out of recipes/wip/x11
and their tarballs fetched and blake3-verified.

This is the case for xcb on Wayland, not X11 nostalgia: KDE's XWayland
integration and Qt's xcb platform plugin both reference these.
2026-08-04 23:23:03 +03:00
vasilito 83ade35754 plasma-desktop: disable the tablet KCM pending a libwacom port
plasma-workspace now builds and installs, so plasma-desktop configured for the
first time and stopped at:
  The following required packages were not found: - libwacom

kcms/tablet requires libwacom (CMakeLists.txt:175), which is not ported -- it
needs libgudev plus upstream's tablet-definition database. Disabled via
upstream's own option (CMakeLists.txt:44, default ON), not an invented switch;
it gates exactly three sources (tabletsmodel.cpp, kcmtablet.cpp,
tabletmoduledata.cpp) and nothing else in plasma-desktop is affected.

THIS REMOVES THE DRAWING-TABLET SETTINGS MODULE. Tracked as a real port; the
option goes back ON in the same change that lands libwacom.
2026-08-04 23:15:53 +03:00
vasilito 3fd2c9a785 plasma-workspace/desktop: install with DESTDIR, not --prefix
plasma-workspace COMPILED AND LINKED COMPLETELY and then failed at install:
  file INSTALL cannot copy ".../libnotificationmanager/plasmanotifyrc"
  to "/etc/xdg/plasmanotifyrc": Permission denied

`cmake --install --prefix` re-roots only RELATIVE destinations. KDE's
KDE_INSTALL_FULL_* paths are absolute, so cmake tried to write into the BUILD
HOST's /etc -- only the host's permissions stopped it from polluting the host
filesystem. DESTDIR re-roots absolute destinations too. Same fix already
applied to kf6-ktexteditor, kde-cli-tools and sddm.

plasma-desktop gets the same fix pre-emptively: it ships /etc/xdg config and
has never been built, so this would otherwise have cost another full cycle.
54 other KDE recipes use the --prefix form but install nothing to an absolute
path, which is why they build clean; left alone rather than churned.
2026-08-04 23:06:32 +03:00
vasilito 0aa4457a86 relibc: advance submodule for libcrypt.a/libutil.a compat archives
kcm_users failed with 'ld: cannot find -lcrypt' although libc.a exports crypt
and crypt_r. relibc now ships empty libcrypt.a/libutil.a so the link resolves
from libc, matching what it already does for libdl/libpthread/librt.
2026-08-04 22:25:02 +03:00
vasilito ab7cc543b8 gate-kx11extras: also guard fixx11h.h and netwm.h
KWindowSystem ships fixx11h.h (X11 macro cleanup), netwm.h and netwm_def.h
(EWMH) only with its X11 component, so a Wayland-only install lacks them. They
carry no X11/ or xcb/ path prefix, so the prefix-only rule missed them:
  logout-greeter/shutdowndlg.cpp:51: fatal error: fixx11h.h: No such file

The single remaining unguarded case is libtaskmanager/xwindowtasksmodel.cpp,
which upstream excludes from the build via if(HAVE_X11) in
libtaskmanager/CMakeLists.txt -- it is never compiled, so it is left alone
rather than edited for appearance.
2026-08-04 22:16:38 +03:00
vasilito 270d0c9ff6 gate-kx11extras: ensure config-X11.h is in scope when converting #ifdef
Converting `#ifdef HAVE_X11` to `#if HAVE_X11` changes the question from "does
this macro exist" to "what is its value", so the definition must actually be in
scope. Doing the conversion without guaranteeing the include turned a silently
inert guard into a hard error:

  shell/panelview.h:13: error: 'HAVE_X11' is not defined, evaluates to 0

KDE builds with -Werror=undef, so an undefined macro in #if is fatal. The
previous commit fixed the guard form and introduced this; the transform now
inserts #include <config-X11.h> when it converts a guard in a file that lacks
it.

Verified: panelview.h now carries the include, and a second run is a no-op.
2026-08-04 22:08:50 +03:00
vasilito d1bc7a2d8f cook: name the recipe and URL when an offline fetch has no source.tar
fetch_offline hashed source.tar BEFORE checking it exists, so a missing tarball
surfaced as
  repo: failed to fetch: Opening file for blake3 failed at
  "recipes/x11/libice/source.tar": No such file (os error 2)
which names neither the recipe nor the remedy. That message sent me to work
around the symptom by hand twice -- libogg/libvorbis, then four newly promoted
X11 recipes -- because it points at hashing rather than at a missing download.
Now it reports the recipe, the upstream URL and the exact curl command.

Also drops libice/libsm from redbear-full. They are X11 session-management
libraries used only by ksmserver, which sits inside if(WITH_X11) and is not
built, and they need xorg util-macros, which no recipe in the tree provides.
Including them would have meant porting a build dependency for code that is
never compiled.
2026-08-04 22:00:11 +03:00
vasilito 218a1f86b0 x11: promote the xcb/X11 client stack out of wip and wire it into redbear-full
Reverses this session's approach. Gating X11 out kept producing failures in a
new syntactic shape each build -- API calls, else-chains, standalone statements,
inert #ifdef guards, bare X11/xcb includes, namespace definitions -- six shapes,
each needing its own rule in gate-kx11extras.py. Providing the real headers and
libraries removes the cause rather than adding a seventh rule.

The stack was already ported and building; it was just parked in recipes/wip.
Verified before promoting: xcb-proto, libxcb, libx11, x11proto and xtrans cook
(cached from earlier builds), libxrender and libxft built successfully, and the
key headers are staged -- xcb/xcb.h, X11/Xlib.h, X11/Xft/Xft.h -- with 25 libs
and 33 headers from libxcb alone. Real upstream releases pinned by blake3
(libxcb 1.17.0, libX11 1.8.12), not stubs.

Promoted: x11proto-kb, xtrans, xcb-proto, libxcb, libx11, libxdmcp, libxext,
libxfixes, libxi, libxrender, libxft, libice, libsm (recipes/x11/) and
libpthread-stubs (recipes/libs/). x11proto was already in the config.

xcb is needed on Wayland too -- Qt's xcb platform plugin, libxkbcommon-x11 and
KDE's XWayland integration all reference it -- so this is not X11-only value.
These remain CLIENT libraries: isPlatformX11() stays false at runtime and the
X11 paths do not execute unless Xwayland is up. The port buys compilation
compatibility, not X11 functionality.
2026-08-04 21:50:13 +03:00
vasilito d8d2ed837c gate-kx11extras: guard namespace blocks using QX11Application
libtaskmanager/virtualdesktopinfo.cpp defines namespace X11Info at namespace
scope in terms of QNativeInterface::QX11Application, which does not exist in a
Qt built without the xcb platform:
  error: 'QX11Application' is not a member of 'QNativeInterface'

All three call sites were already inside #if HAVE_X11 -- only the definition
was exposed -- so wrapping the block changes no reachable behaviour.

Restricted to depth-0 'namespace' blocks whose body names an X11-only native
interface. Narrow on purpose: brace-matching arbitrary function definitions is
much easier to get wrong, and a bad transform here produces invalid C++ rather
than a clean failure.
2026-08-04 21:26:14 +03:00
vasilito e3b1edacef gate-kx11extras: guard bare X11/xcb includes outside HAVE_X11
Distinct from the KWindowSystem-API gating: these are the Xlib/XCB headers
themselves, which a Wayland-only sysroot does not ship, so each is a hard
compile failure rather than a lost feature:
  appmenu/appmenu.h:13: fatal error: xcb/xcb.h: No such file or directory

Two of the affected directories are genuinely compiled and would have failed in
turn: kcms/kfontinst (gated only on FONTCONFIG_FOUND) and logout-greeter
(CMakeLists.txt:428, outside any X11 gate). kcms/cursortheme is already gated
upstream by `if(WITH_X11 AND X11_Xcursor_FOUND)` and ksmserver by if(WITH_X11);
guarding them too is harmless and keeps the rule uniform rather than
maintaining a list of exceptions.

Only touches includes at preprocessor depth 0 with respect to HAVE_X11, so
anything already guarded is left alone.

Verified: preprocessor balance OK across all 59 files carrying guards, and a
second run is a no-op (0 files, 0 includes) -- the recipe re-runs this on every
build, so idempotency is a correctness requirement, not a nicety.
2026-08-04 21:24:41 +03:00
vasilito 70b215f945 gate-kx11extras: fix inert #ifdef HAVE_X11 guards
config-X11.h.cmake declares the macro with `#cmakedefine01 HAVE_X11`, which
always DEFINES it -- as 0 when X11 is off, not undefined. So `#ifdef HAVE_X11`
is true in BOTH configurations and the guard does nothing:

    #ifdef HAVE_X11
    #include <xcb/xcb.h>      <- compiled even with HAVE_X11 == 0
    #endif

That is how appmenu.h reached
  appmenu/appmenu.h:13:10: fatal error: xcb/xcb.h: No such file or directory
while looking correctly guarded. `#if HAVE_X11` reads the value and behaves as
intended.

An upstream bug invisible on any system that has X11 headers installed, because
there the include just succeeds. 3 occurrences across appmenu.h and
panelview.h; plasma-desktop has none. Normalisation runs on every file rather
than only those using the X11-only KWindowSystem APIs, since the defect is
about the guard form, not the guarded content.
2026-08-04 21:18:07 +03:00
vasilito 97137e5962 icu: add .note.GNU-stack to the data object via objcopy
-Wa,--noexecstack did not reach icudt75l_dat.o: ICU builds it through pkgdata,
which drives the assembler with its own flags and ignores CFLAGS. Verified
empirically -- after a full ICU rebuild readelf still showed 0 GNU-stack
sections, and plasma-workspace failed identically.

Patching the archive member is deterministic where the flag was not. The added
section is empty and read-only: it declares a non-executable stack, which is
exactly true for a pure data blob. Verified objcopy 0 -> 1 section on the real
archive before committing.

Without it, binutils warns "missing .note.GNU-stack section implies executable
stack", and KDE's ECM links with -Wl,--fatal-warnings, so every KDE consumer of
static ICU fails (plasma-workspace applets/digital-clock, ld exit 1).

Asserts the section is present afterwards rather than swallowing errors: a
silent no-op here resurfaces as a link failure in a different package, far from
the cause.
2026-08-04 21:07:39 +03:00
vasilito 908987494d plasma-desktop: install KSMServerDBusInterface, gate X11-only KWindowSystem APIs
Both found by pre-checking plasma-desktop against the failure classes already
catalogued, before it was ever attempted -- rather than discovering them one
~15-minute build at a time.

1. KSMServerDBusInterface. plasma-desktop hard-requires it (CMakeLists.txt:191,
   CONFIG REQUIRED), but upstream generates it in ksmserver/CMakeLists.txt and
   add_subdirectory(ksmserver) sits inside if(WITH_X11) -- OFF here -- so a
   Wayland-only build never installs it. Only the D-Bus INTERFACE is needed:
   the XML is a platform-independent description and upstream's
   KSMServerDBusInterfaceConfig.cmake.in is a single variable pointing at it.
   ksmserver itself is X11-only (links X11::X11/SM/ICE and PW::KScreenLocker)
   and stays unbuilt. XML copied verbatim from the upstream tree. Same shape and
   same remedy as kscreenlocker.

   KRunnerAppDBusInterface, also REQUIRED by plasma-desktop, needs nothing:
   add_subdirectory(krunner) is outside the X11 gate.

2. X11-only KWindowSystem headers, reusing gate-kx11extras.py unchanged:
   KX11Extras (4 files), KUserTimestamp (1), KWindowInfo (2).

Dry-run on the plasma-desktop tree: 3 files gated, 5 includes, 6 blocks;
preprocessor balance OK across all 5 files carrying guards; no malformed
'#endif <code>'; no unguarded references left. Source restored afterwards --
the recipe applies this at build time.
2026-08-04 21:03:01 +03:00
vasilito f25ccf07c6 icu: assemble the data blob with --noexecstack; gate continuation comments
ICU emits its data as generated assembly (icudt75l_dat.S). Without
-Wa,--noexecstack the assembler produces an object with no .note.GNU-stack
section, and modern binutils warns:
  ld: warning: icudt75l_dat.o: missing .note.GNU-stack section implies
      executable stack
Harmless alone -- except KDE's ECM links with -Wl,--fatal-warnings, so every
KDE consumer of static ICU fails outright (first hit: plasma-workspace
applets/digital-clock, collect2: error: ld returned 1). Fixed at the source
rather than suppressed downstream, which would have to be repeated per consumer.

Also gates the '#'-inside-a-backslash-continuation trap, which terminates the
continuation and silently drops every remaining argument. It has now bitten
three times, most recently while writing THIS commit: the noexecstack rationale
was first placed between two continued configure flags, which would have
dropped the rest of ICU's configure line. Moved above the invocation.

The check scans the RAW file, not the parsed TOML. In a multi-line basic string
a trailing backslash is itself a TOML line-continuation escape, so the newline
is gone before the value is handed over and the parsed string has no trailing
backslashes at all. The first version scanned the parsed value and silently
found nothing -- caught by a self-test, not by review, which is the same class
of invisible failure the gate exists to prevent.
2026-08-04 20:58:50 +03:00
vasilito cb7764b6d9 plasma-workspace: link libicudata for the static ICU build
ICU is built static here (--enable-static --disable-shared, and
--with-data-packaging=static), so the data blob lives in libicudata.a. CMake's
builtin FindICU exposes ICU::uc and ICU::i18n but not ICU::data, and a static
archive carries no DT_NEEDED to pull the data in the way libicuuc.so would on a
normal system. The digital-clock plugin failed to link:

  udata.cpp:(.text+0xea1): undefined reference to `icudt75_dat'

STANDARD_LIBRARIES rather than LINKER_FLAGS: the latter is emitted before the
object files, where a static archive contributes nothing. Same reasoning as the
-lgcc entry in redox-toolchain.cmake.

Scoped to this recipe rather than the shared toolchain: not every recipe using
that toolchain stages ICU, so a blanket -licudata would become "cannot find
-licudata" for them.
2026-08-04 20:47:36 +03:00
vasilito 89fe82e77a kwin: remove comment truncating the cmake invocation; screenlocker OFF
Two coupled problems, both restored by the `git checkout -- local/recipes/`
revert that undid this session's uncommitted recipe work.

1. A '#' comment block sat INSIDE the backslash-continued cmake invocation. A
   comment line terminates the continuation, so every flag after it was silently
   dropped -- SCREENLOCKER, TABBOX, GLOBALSHORTCUTS, RUNNERS and the rest took
   cmake's defaults instead of the values written here. The recipe already
   carries a NOTE warning about exactly this trap; the rationale text is now
   above the invocation where it cannot truncate anything.

2. With the flag dropped, KWIN_BUILD_SCREENLOCKER defaulted ON, and kwin gates
   find_package(KScreenLocker) on it (source/CMakeLists.txt:376), so configure
   aborted:
     The following REQUIRED packages have not been found:
      * KScreenLocker  For screenlocker integration in kwin_wayland
   kscreenlocker ships only the ScreenSaverDBusInterface package; the library
   still needs its Wayland-only port.

Set OFF explicitly. THIS MEANS THERE IS NO LOCK SCREEN -- documented at the flag
and in the kscreenlocker recipe. Turn it back ON in the same change that lands
the library port.

Verified: 0 comment lines remain inside the invocation.
2026-08-04 20:35:41 +03:00
vasilito 0a8922a544 qtdeclarative: enable qml_network
QQmlEngine::networkAccessManager() exists only under QT_CONFIG(qml_network),
a qtdeclarative feature separate from QT_FEATURE_network, which was already ON.
kirigami failed on it:
  src/primitives/icon.cpp:469: 'class QQmlEngine' has no member named
  'networkAccessManager'

qtbase builds libQt6Network here, so enabling the feature restores kirigami's
remote icon loading instead of compiling the capability out.
2026-08-04 20:08:40 +03:00
vasilito 6f5657b075 kscreenlocker: restore the interface-only recipe
This rewrite was lost when `git checkout -- local/recipes/` reverted every
uncommitted recipe edit, so the full-build version came back and the build tried
to compile the X11 locker on a Wayland-only target:
  globalaccel.cpp:8         fatal error: KKeyServer
  x11locker.h:15            fatal error: X11/Xlib.h
  greeter/greeterapp.cpp:63 fatal error: X11/Xatom.h

plasma-workspace needs only ScreenSaverDBusInterface (CMakeLists.txt:127), used
in three qt_add_dbus_interface calls that generate a D-Bus client proxy from the
XML; it never links the library. The one consumer that does link
PW::KScreenLocker is ksmserver, which sits inside if(WITH_X11) and is not built.

The library port (~61 X11/XCB sites) and KWIN_BUILD_SCREENLOCKER remain open
work, documented in the recipe. Both installed files are verbatim upstream
artefacts -- nothing fabricated.
2026-08-04 20:06:58 +03:00
vasilito 5570ab1255 cook: fail a build that stages no files
A recipe whose script exits 0 but installs nothing currently reports success,
and the damage lands far from the cause. qtspeech produced a 136-byte package
because upstream `return()`s with only a NOTICE when Qt6::Multimedia is absent;
that surfaced much later as an unresolved symbol in a consumer, not as a
qtspeech failure.

Zero regular files staged is unambiguous -- every real package installs at
least one file -- so this needs no per-recipe size threshold and cannot
false-positive on a small-but-valid package. The error names the likely cause
(a configure step soft-bailing on a missing optional dependency) rather than
just reporting emptiness. Metapackages that genuinely stage nothing opt out by
mentioning COOKBOOK_ALLOW_EMPTY_PACKAGE in their script.

This is the same failure shape as the libudev/libpciaccess API-surface risk: a
gap that reports success locally and only becomes visible as a link error in
something downstream.
2026-08-04 20:00:25 +03:00
vasilito d7cfa84258 recipes: record upstream provenance for libepoxy, libxcvt, libdisplay-info
These three carried only `path = "source"` with no origin recorded anywhere, so
nothing could distinguish them from Red Bear's own code and the first-party
integrity gate classified them as ours. URLs and versions taken from evidence
in each source tree, not guessed:
  libepoxy         github.com/anholt/libepoxy            meson version 1.5.10
  libxcvt          gitlab.freedesktop.org/xorg/lib/libxcvt   meson version 0.1.3
  libdisplay-info  gitlab.freedesktop.org/emersion/...   meson version 0.4.0

NOT applied to libpciaccess or libudev, which were named alongside these as
upstream. Their source trees are 2 files / 272 lines and 3 files / 1314 lines
respectively -- these are Red Bear's own minimal implementations of those APIs,
not vendored copies of the upstream projects, which are far larger. Recording a
fake upstream for them would downgrade the gate from fatal to a warning on
first-party code, which is the one error direction that loses work that exists
nowhere else. Flagged for confirmation rather than assumed.
2026-08-04 19:41:35 +03:00
vasilito 36ddc1f2db verify-tracked-sources: brush is a fork, match provenance case-insensitively
brush records `# Upstream: https://github.com/reubeno/brush`, but the check
matched `upstream:` case-sensitively AND required the URL to end in .tar/.git,
so it missed on both counts and filed a genuine fork as first-party.

Now matches an explicit upstream/snapshot/origin label followed by a URL, any
case. Deliberately NOT any bare URL in a comment: a stray bug-tracker link must
never read as provenance, since that error direction (first-party treated as
vendored) is the one that loses irreplaceable work.

Remaining inaccuracy is missing DATA, not detection. libepoxy, libpciaccess,
libudev, libxcvt and libdisplay-info are upstream projects whose recipes carry
only `path = "source"` with no origin recorded anywhere, so nothing can tell
them apart from our own code. They classify first-party, which is merely
stricter. The real fix is to record their upstream in the recipe.
2026-08-04 19:39:06 +03:00
vasilito 156aa386b3 verify-tracked-sources: derive first-party status, don't list it
The name list was wrong in principle. It started as redbear-*, then needed cub,
then tlc -- and protection that depends on someone remembering to edit this file
is not protection. A new internal program starts out unguarded and the omission
stays invisible until the code is already gone. tlc proved it: first-party,
exempt from out-of-tree staging, protected by nothing but this gate, and
matching no pattern.

The real property is structural -- our code has no upstream to restore from. A
recipe is first-party when its recipe.toml records no fetchable origin: no
`tar =`, no `git =`, no upstream URL. That identifies ~96 recipes against the 3
the list covered, so the list was guarding roughly 3% of the exposure.

The heuristic errs toward first-party deliberately. A vendored recipe recording
its origin only in prose gets treated as ours, which just makes drift fatal
instead of a warning. The opposite error loses irreplaceable work, so the
default fails in the safe direction.

Verified: fires on redbear-netctl, cub and tlc (none of which are named
anywhere in the code now); does NOT fire on vendored kirigami; silent on a
clean tree; every probe restores.
2026-08-04 19:36:00 +03:00
vasilito d1bc24d61e verify-tracked-sources: cub and tlc are first-party too
Extends the fatal first-party check beyond redbear-* to cub (system) and tlc
(tui). Both are Red Bear's own programs with no upstream anywhere, so the
"restore it from the tarball" recovery that makes vendored drift a warning does
not exist for them.

They sit on opposite sides of the staging boundary, which is why both need the
gate for different reasons:
  cub  is staged out of tree (no escaping cargo path deps), so staging already
       keeps recipe seds off the tracked copy.
  tlc  is EXEMPT from staging: its manifest has a path dependency escaping the
       source tree, so nothing keeps a sed off the real files. For tlc this
       gate is the only protection.

The check is now a redbear_is_firstparty() helper rather than an inline glob, so
adding the next internal program is one line.

Verified: silent on a clean tree; fires on a one-line edit to cub and to tlc;
both restore cleanly.
2026-08-04 19:33:55 +03:00
vasilito 8eaf54d87f verify-tracked-sources: first-party redbear-* drift is fatal
redbear-* recipes are not vendored upstream code -- they are Red Bear's own
programs and exist nowhere else. A vendored tree can be restored from its
tarball or git remote; first-party source cannot. If a recipe sed or an `rm`
damages it and that gets committed, the work is gone.

Not hypothetical. Seven redbear-* recipes rewrite their own source during the
build (greeter, btusb, btctl, ime, dnsd, accessibility, keymapd), and all seven
are exempt from out-of-tree staging because their cargo manifests carry path
dependencies escaping the source tree. They are simultaneously the least
protected and the most irreplaceable code here.

Uncommitted drift in them now fails preflight instead of printing a note that
scrolls past. Vendored trees keep the existing warn-by-default behaviour.
Override: REDBEAR_ALLOW_DIRTY_FIRSTPARTY=1.

Verified: gate is silent on a clean tree, fires on a one-line edit to
redbear-authd, and the tree restores cleanly.
2026-08-04 19:30:37 +03:00
vasilito 130f37de8b cook: don't stage recipes with cargo path deps escaping their source
redbear-greeter's manifest has
  redbear-login-protocol = { path = "../../redbear-login-protocol/source" }
Cargo resolves that relative to the manifest, so out-of-tree staging pointed it
at <recipe>/target/redbear-login-protocol/source:
  failed to read .../target/redbear-login-protocol/source/Cargo.toml
  No such file or directory (os error 2)

Rewriting the manifest would silently change dependency paths behind the
recipe's back. Leaving these in tree is the honest option: they are cargo
recipes that do not sed their source, so the mutation risk staging exists to
prevent does not apply to them.
2026-08-04 19:24:40 +03:00
vasilito 85462821a2 build: serialise recipe cooking by default; auto-reset stale cmake caches
Two systemic fixes for failure classes this session kept re-hitting.

1. COOK_JOBS default 4 -> 1. Recipes are not isolated: redbear_qt_ensure_dep_
   sysroots repairs OTHER recipes' sysroots, so one cook can relink the include/
   or lib/ directory another is compiling against. The tell was a failure that
   MOVED between source files across runs (kirigami died in KirigamiTemplates on
   build 59, KirigamiPrivateplugin on 61) with a sibling's rm -f/ln -sf
   interleaved in the log. Making the relink atomic closed one window; the
   sharing itself remains unsound. Compilation is still parallel -- each recipe
   keeps the full -j budget -- only the number of recipes in flight drops to 1.
   An intermittent build costs more than a serial one.

2. Auto-reset build dirs whose CMakeCache records a different source path.
   CMake stores CMAKE_HOME_DIRECTORY and hard-aborts when the source moves:
     CMake Error: The source ".../source-staged/..." does not match the source
       ... used to generate cache
   Out-of-tree staging moved every tracked recipe's source and stranded 66 build
   dirs. Two rounds of clearing them by hand were not a fix: the next source-path
   change strands them again, and the abort surfaces in a downstream recipe
   rather than at the cause. cook now detects the mismatch and resets the dir.
2026-08-04 19:05:25 +03:00
vasilito 36554161cb verify-patch-sanity: skip source-staged, the out-of-tree copy of source/
Out-of-tree staging made the checker scan source-staged/, which holds the same
upstream third-party patches as source/ -- already skipped because they are not
ours to fix. qtdeclarative's bundled yoga patch then failed the build at
preflight. Same rationale as the existing /source/ entry.
2026-08-04 18:26:44 +03:00
vasilito a591bee846 cook: don't stage submodules; refresh staged source in place
Two defects in the out-of-tree staging from 221a91cba4/a3d9240d62, both found
by actually running it rather than by inspection.

1. Submodules were staged. `git ls-files --error-unmatch` succeeds on a
   gitlink, so relibc looked like an ordinary tracked tree and was copied
   wholesale, losing the nested-repo context cargo needs -- crt0, crti, crtn
   and ld_so all failed to build. Fork submodules are already covered by the
   stricter REFUSING-TO-BUILD dirty gate, so skipping them loses no protection.

2. `rm -rf` before the copy made the staged path vanish mid-build. Qt bakes its
   COOKBOOK_SOURCE into installed cmake files (QtSeparateDebugInfo.cmake
   try_compile()s ${QT_SOURCE_TREE}/config.tests/...), so once that path was the
   staged tree, rebuilding qtbase pulled it out from under consumers:
     CMake Error: The source ".../qtbase/.../source-staged/config.tests/
       binary_for_strip/CMakeLists.txt" does not ...
   (qtsvg and qtshadertools). Now rsync -a --delete refreshes in place: same
   pristine result, but the directory never stops existing. Verified with 4000
   probes across a full kirigami rebuild -- 0 observations of it missing.

Staging is confirmed working: a 26-package run staged 10 trees, skipped relibc,
and left 0 dirty tracked source files (previously 22-29).
2026-08-04 18:10:52 +03:00
vasilito 7ae9646968 qt-sysroot: relink dependency sysroots atomically
redbear_qt_ensure_dep_sysroots repairs OTHER recipes' sysroots, so with
COOKBOOK_COOK_JOBS>1 it runs while a parallel cook is compiling against the
very directory it is relinking. It did `rm -f` then `ln -sf`, leaving a window
where the path did not exist. kirigami died in that window:

  cstdio:47: fatal error:
    .../qtdeclarative/target/.../sysroot/include/stdio.h: No such file

with another cook's `rm -f`/`ln -sf` on qtdeclarative's sysroot interleaved in
the same log.

Now: skip entirely when the link already points at the right target (the
common case, and the cheapest way to stop the churn), otherwise replace via
ln -s to a temp name + `mv -T`, a single rename(2) -- readers see the old link
or the new one, never nothing.

Verified with 300 concurrent relinks against 3000 probes: 0 missing
observations, where the old sequence reproduced the gap.
2026-08-04 17:54:01 +03:00
vasilito a3d9240d62 cook: resolve symlinks before the tracked-source check
redbear-ci / check (push) Has been cancelled
The out-of-tree staging added in 221a91cba4 never actually ran. Recipes are
reached through the overlay path `recipes/<cat>/<name>`, a symlink into
`local/recipes/...`, and `git ls-files --error-unmatch` refuses any pathspec
that traverses a symlink ("pathspec is behind a symbolic link"). The check
therefore reported every tracked vendored tree as untracked, staging was
skipped, and builds went on mutating git-tracked sources -- 22 dirty source
files after a 42-package run.

Canonicalize the path before both the git query and the copy. Verified: the
check fails via the symlink, succeeds via the resolved path, and cooking
kirigami now logs

  [out-of-tree] staged tracked source -> .../kirigami/target/.../source-staged

with the recipe's sed rewriting the staged copy instead of the tracked tree.
2026-08-04 17:50:14 +03:00
vasilito 27ca9bc4b0 relibc: advance submodule for timerfd/signalfd C linkage
Points the relibc submodule at 4e9fbf4c. sys/timerfd.h and sys/signalfd.h
declare their prototypes in the cbindgen trailer, which is emitted outside the
extern "C" block cpp_compat generates, so C++ consumers linked against a
mangled name while relibc exports the plain C symbol:

  alignedtimer.cpp:(.text+0x29a): undefined reference to
      `timerfd_create(int, int)'

(plasma-workspace libclock). C callers were unaffected, which is why it
survived until a C++ consumer appeared.

Also refreshes the tracked-source baseline. This should become largely static
now that cook stages tracked vendored sources out of tree.
2026-08-04 16:49:56 +03:00
vasilito 221a91cba4 build: port libcanberra, gate X11-only KWindowSystem APIs, build out of tree
libcanberra: plasma-workspace calls find_package(Canberra) TYPE REQUIRED and
includes <canberra.h> from four translation units with no HAVE_CANBERRA guard,
one of them libnotificationmanager (the core notification library). It cannot
be made optional, so it is ported for real. Built shared: it dlopens its
backend through libltdl, the libtool recipe stages libltdl.so only (no .a), so
a static build left every consumer with an undefined lt_dlopenext.

Audio is SILENT. Upstream 0.30 offers alsa/oss/pulse/gstreamer/null and none
speak Redox; the pulse driver needs PulseAudio's client library, which PipeWire
does not provide. The null driver is real upstream code, so the API/ABI is
genuine and all consumers work -- but nothing reaches the speakers until a
native /scheme/audio driver exists.

KX11Extras et al: gate the five X11-only KWindowSystem headers behind the
HAVE_X11 that plasma-workspace already defines. X11 is compiled OUT, not added.
gate-kx11extras.py brace-matches each block and keeps any trailing else outside
the guard, since wrapping a whole if/else-if chain yields invalid C++.

check-recipe-escapes.py: a single backslash in a TOML multi-line string is a
TOML escape, so a sed written as \bFoo\b parses to <BS>Foo<BS> and silently
matches nothing -- no TOML error, no sed error. This class bit the tree three
times. Now gated in preflight; it also found openssh, which used an invalid \$
and could not be parsed by any compliant parser.

cook_build.rs: build git-tracked vendored sources OUT OF TREE. Recipe scripts
rewrite their source, so builds were mutating version-controlled files: a
no-op sed became indistinguishable from a working one, and the integrity gate
fired so often that clearing it stopped being protective. Uses
cp -a --reflink=auto, not cp -al: sed -i is link-safe but `cp -f` and `>`
truncate in place and would write through a hard link into the tracked
original. Content hashing still runs against the pristine tree, so hashes now
describe committed state. Escape hatch: REDBEAR_IN_TREE_BUILD=1.
2026-08-04 16:41:39 +03:00
vasilito fd11aa716c feat: port the missing KDE Plasma dependency chain and harden the auth stack
redbear-ci / check (push) Has been cancelled
Unblocks plasma-workspace/plasma-desktop, which required 14 packages that had
no in-tree recipe. Sources are reproducible from each recipe's tar= + blake3;
the vendored source/ trees are deliberately not committed here (212M).

New recipes:
  KF6 6.28.0   kf6-kholidays, kf6-krunner, kf6-kstatusnotifieritem,
               kf6-kunitconversion
  Plasma 6.7.2 knighttime, layer-shell-qt, libkscreen, libksysguard,
               plasma-activities-stats, plasma5support, kscreenlocker
  Qt 6.11.1    qtpositioning, qtspeech, qttools

libksysguard carries P0-redox-process-backend.patch: processes_local_p.cpp
dispatches on platform macros and had no __redox__ arm, so ProcessesLocal was
entirely undefined. Adds a real backend reading /scheme/proc/ps (pid, ppid,
real+effective ids, thread count, state) and /scheme/sys/mem, with kill() for
signals. Upstream's generic fallback is a pure stub and was not used. Absent
facilities (no setpriority/sched_setscheduler/ioprio on a microkernel) report
NotSupported rather than pretending.

Restored, no longer disabled:
  - night colour: kcms/nighttime + kwin's nightlight plugin, now that
    KNightTime/Qt6Positioning/KF6Holidays exist
  - KIO FileWidgets (file dialog, places model), wrongly swept in with the
    unportable kiod/kssld/kioworkers subdirs
  - kf6-ktexteditor text-to-speech: removes a disguised stub that rewrote
    speechEngine() to return nullptr and mangled call sites into invalid C++
  - kwin KWIN_BUILD_SCREENLOCKER=ON (needs kscreenlocker; see below)

Toolchain and recipe fixes:
  - redox-toolchain.cmake: append -lgcc. __extendhfsf2/__extendbfsf2 are
    global in libgcc.a but hidden in libgcc_s.so (the Redox libgcc version map
    stops at GCC_7.0.0 and never emits the GCC_12/13 nodes upstream exports),
    and GCC omits -lgcc for -shared, so no C++23 shared library using
    std::format<_Float16|bfloat16_t> could link.
  - qtmultimedia: rewrite /usr/src/.../meta_types paths and stage metatypes,
    so consumers using qt_internal_add_qml_module can configure.
  - qtspeech: qtmultimedia is mandatory, not optional -- upstream return()s
    with only a NOTICE without it, yielding a green build over an empty
    package. Asserts its own output so that cannot recur.
  - narrow Linux-only guards with AND NOT REDOX where the toolchain sets
    CMAKE_SYSTEM_NAME=Linux purely to get UNIX=TRUE (kio LibMount,
    libksysguard NL/Sensors, plasma-workspace NetworkManagerQt).
  - drop REQUIRED components that are declared but referenced nowhere
    (Location, QCoro6, Qt6 Test) -- verified by exhaustive grep.
  - DESTDIR installs where KDE emits absolute KDE_INSTALL_FULL_* paths that
    --prefix cannot re-root, which otherwise write into the build host.

Auth stack:
  - pam-redbear: add PAM_MODULE_UNKNOWN (28), missing from both the header and
    lib.rs; realign 30/31 to Linux-PAM's PAM_CONV_AGAIN/PAM_INCOMPLETE, which
    previously held Red Bear-only names on standard values, so anything built
    against stock PAM headers mis-decoded them.
  - redbear-authd: support yescrypt ($y$ -- the default shadow format on
    current Debian/Ubuntu/Fedora, previously an unexplained login failure),
    bcrypt and md5-crypt. Plaintext shadow entries now require the
    /etc/redbear/allow-plaintext-passwords sentinel and warn on every use,
    instead of being compared silently. 19/19 host tests pass.

Build-system hardening:
  - verify-tracked-sources.sh, wired into preflight: fails on deletion of any
    tracked vendored source, and on modifications with no baseline entry.
    local/sources/ had a dirty gate and version checks; local/recipes/*/source/
    had none, which allowed an rm -rf to delete 7958 tracked files and a
    pristine re-extract to silently overwrite committed fixes (kwin's
    std::expected/vulkan-hpp and X11 gating, kio's Q_OS_REDOX resolver guards).
  - validate-source-trees.py: resolve recipe.toml through the overlay symlink;
    it reported false MISSING for symlinked recipes.
  - test-sddm-virgl-qemu.sh: the null-proxy check used report(), which PASSES
    on regex match -- so the known Qt6 Wayland null+8 fault would report PASS
    when present. Added report_absent().

kscreenlocker builds only its cmake-level Wayland-only changes so far; the
C++ X11 removal (61 call sites) is not yet applied, so kwin's screenlocker
flag is blocked on it.
2026-08-04 10:06:39 +03:00