syscall
submodule/syscall had diverged from origin -- 18 local commits against
19 on the remote, with matching subjects and different SHAs, i.e. the
local branch had been rewritten at some point. Rather than force-push
and discard 19 published commits, rebased local onto
origin/submodule/syscall. git absorbed 16 duplicates by patch-id,
leaving two genuinely local commits (NUMA support, which origin does
not have at all, and the 0.3.2 version bump).
Verified no work was lost: the rebased tree is byte-for-byte identical
to the pre-rebase state apart from the Cargo.toml version line, and a
backup/pre-rebase-* branch is kept. Two Cargo.toml conflicts were
version-label collisions only, resolved to 0.9.1+rb0.3.1 mid-series and
0.9.1+rb0.3.2 at the tip, per the Cat 2 convention. The push is now a
fast-forward and the gitlink is updated to the rebased SHA.
native toolchain
gcc-native and rust-native set to "ignore" -- explicit operator
decision, 2026-08-03: 'Treat gcc-native/rust-native as a separate
workstream, explicitly deferred by me, for now.' That is the one
condition AGENTS.md ABSOLUTE RULE permits an exclusion under. It is not
an agent-initiated removal, and not a repeat of the 'not needed for
greeter proof' hand-wave that previously hid real breakage -- that
suppression was reverted first, which is how the defects were found.
binutils-native and llvm-native stay in the target; llvm-native is
required for libclc and Mesa's iris/radeonsi CLC path. The recipes for
the deferred pair are fixed and committed, not reverted.
Follows the recipe's [source] move from same_as gcc13 to
path = "../gcc16/source". The old symlink pointed at
recipes/dev/gcc13/source and survived the recipe edit, which is why the
first GCC 16 build attempt was still compiling GCC 13 sources.
libiberty compiles getopt1.c against GCC's include/getopt.h, which
declares the GNU-internal _getopt_internal. relibc ships a getopt.h that
does not declare it and was shadowing GCC's:
getopt1.c:71: error: implicit declaration of function
'_getopt_internal'
Same shape as the cpuid.h shadowing already handled in recipes/dev/gcc13.
Verified: _getopt_internal errors 5 -> 0.
STILL FAILING, on a new and different phase: the HOST libstdc++ headers
are being pulled into the build --
/usr/include/c++/16/x86_64-pc-linux-gnu/bits/os_defines.h:44:
error: missing binary operator before token '('
which is __GLIBC_PREREQ evaluated where there is no glibc. That is a
host/target header leak, not a continuation of the getopt problem, and it
is unrelated to this commit's change.
Two corrections.
relibc dependency restored. Dropping gcc13 from gcc-native's deps also
removed what transitively staged relibc's headers, leaving the sysroot
with no libc headers at all -- no fenv.h, so libstdc++'s <cfenv> failed
with 'fenv_t has not been declared in ::'.
That corrects my earlier diagnosis: relibc's fenv.h is NOT a stub. It
delegates to openlibm_fenv.h, which dispatches on __x86_64__ to
openlibm_fenv_amd64.h where fenv_t and fexcept_t are both defined, and
relibc stages all of those headers. The header was simply never reaching
this recipe's sysroot. The previous commit message asserting a relibc
fenv gap was wrong.
relibc gitlink bumped for the fnmatch commit, which adds the GNU
FNM_FILE_NAME and FNM_LEADING_DIR that GCC 16's libiberty needs.
Repointed [source] from the gcc13 recipe to the Redox-ported GCC 16 tree
(local/recipes/dev/gcc16/source, upstream 16.1.0 + gcc-redox-port), which
is what produced the working cross toolchain in prefix/.
Building GCC 13 with the GCC 16 cross compiler was not a supported
configuration and each fix only revealed the next incompatibility -- a
C++11 pin for libcody, GCC 13's cpuid.h shadowing the toolchain's after
GCC 15/16 removed the withdrawn AVX512PF/ER/4VNNIW/4FMAPS and PREFETCHWT1
macros, and finally an ICE in gimple_build_eh_must_not_throw compiling
libsupc++. All three are gone on GCC 16: ICE 0, char8_t 0, cpuid 0.
Also fixed here:
- The stale same_as symlink (source -> recipes/dev/gcc13/source) survived
the recipe edit and kept feeding GCC 13 sources to the build. Removed.
- gcc13/gcc13.cxx dropped from dependencies: they build the compiler this
recipe no longer uses. The cross compiler comes from the prefix on PATH.
- Exempted from the tree-wide -std=gnu17 pin. That pin exists for the
C17-era recipes, but GCC 16's own sources are C23 and use `bool` as a
keyword: gcc/config/i386/i386.h:1722: unknown type name 'bool'.
- [package].version set explicitly -- same_as used to supply it, and a
path source leaves the cookbook nothing to infer from.
- Version-globbed the hardcoded 13.2.0 libgcc copy paths.
BLOCKED on a genuine relibc gap. libstdc++'s <cfenv> does
using ::fenv_t; using ::fexcept_t;
but relibc's fenv.h is a 3-line stub defining neither, so
libstdc++-v3/include/fenv.h fails. fenv.h is a C99/POSIX header owed
fenv_t, fexcept_t, the FE_* macros and the fe* functions. Implementing it
in the relibc fork is the fix -- per LOCAL-FORK-SUPREMACY-POLICY.md Rule 2
the fork must be complete -- and is real work, not a flag.
Three defects found and fixed, each verified to go to zero:
1. libcody C++ standard. Its configure contains
#if __cplusplus > 201103
#error "C++11 is required"
so anything newer than C++11 is rejected outright. My earlier
-std=gnu++17 tripped exactly this -- the 'C++11 is required' failure
came from build/libcody/config.log, not from a missing libstdc++ as
the previous commit assumed. C++11 also fixes the original problem:
char8_t arrived in C++20, so under C++11 u8"" is still const char[].
char8_t diagnostics: 100+ -> 0.
2. libcody is compiled by the CROSS compiler, not the host one --
x86_64-unknown-redox-g++ ... -c -o buffer.o .../libcody/buffer.cc
because --host is the Redox target. So plain CXXFLAGS is the right
knob, scoped to this branch; the freestanding branch must keep the
compiler defaults.
3. libgcc's cpuinfo.c needs CPUID bit macros from <cpuid.h>. Built by
GCC 16 that resolves to GCC 16's header, and GCC 15/16 REMOVED the
macros for the withdrawn AVX512PF/ER/4VNNIW/4FMAPS and PREFETCHWT1
extensions. GCC 13 ships its own cpuid.h that still defines them, so
its config dir now precedes the toolchain include path for target
compiles. Undeclared-bit errors: 5 -> 0.
BLOCKED, and not by a flag. GCC 16 now ICEs compiling GCC 13's own
libstdc++:
libstdc++-v3/libsupc++/eh_call.cc:39:1: internal compiler error:
in gimple_build_eh_must_not_throw
Each fix has revealed the next incompatibility; an ICE is where
flag-tweaking stops being the answer. Building GCC 13 with GCC 16 is
three major versions of drift and is not a supported configuration.
The coherent fix is to move gcc-native onto GCC 16, which is the whole
point of the port in local/patches/gcc-redox-port/ -- local/recipes/dev/
gcc16/source is already ported and is what produced the working cross
toolchain. That is an operator-level decision, so it is not taken here.
libcody is compiled by the CROSS compiler, not the host one -- the build
log shows
x86_64-unknown-redox-g++ ... -c -o buffer.o .../libcody/buffer.cc
because --host is the Redox target. So plain CXXFLAGS is the right knob,
not CXXFLAGS_FOR_BUILD as the previous commit assumed. Scoped to the
gcc-native branch only.
Verified: char8_t errors go 100+ -> 0.
STILL OPEN. With CXXFLAGS set, the top-level configure now fails its
build-side probe:
checking whether gcc accepts -g... no
configure: error: C++11 is required
The two states are exclusive as things stand:
- CXXFLAGS carrying -std=gnu++17 -> char8_t fixed, C++11 probe fails
- CXXFLAGS without it -> probe passes, char8_t fails
so something in the exported CXXFLAGS is unacceptable to the HOST gcc
that configure probes (the cookbook adds -fno-hardened -DHAVE_ALLOCA_H=1
-fPIC alongside a target -I). The recipe unsets CFLAGS/CPPFLAGS/LDFLAGS
for this branch but leaves CXXFLAGS set, which is the likely culprit --
the next step is to give the build-side compiler its own clean flags
rather than inheriting the target's.
version = "0.2.189" -> "0.2.189+rb0.3.2", per local/AGENTS.md
"Version conventions": every Cat 2 fork is <upstream>+rb<branch>. The
label is what makes the fork traceable to both its upstream base and the
Red Bear branch it was built for.
+rb is build metadata, which semver ignores when matching, so ^0.2
requirements still resolve to the fork -- confirmed, the rust lockfile now
reads libc v0.2.189+rb0.3.2 from the path source. A -rb suffix would be
read as a pre-release and would NOT satisfy them, which is exactly why the
project mandates +rb.
Two things this surfaced:
- fork-upstream-map: libc moved from snapshot to diverged. The fork is
vendored from the crates.io PACKAGE, whose file set differs from the
upstream git tag by construction (no .github/, adds
.cargo_vcs_info.json), so a tag content-diff reported differences that
mean nothing -- 'missing files that exist in upstream' for files the
package never ships. diverged states the real relationship.
- local/recipes/dev/gcc16/.vendored-upstream added. Extracting GCC 16.1.0
put upstream's vendored Rust crates under local/recipes/*/source/, so
sync-versions.sh treated datafrog/log/polonius-engine as Cat 1 in-house
crates and wanted to stamp them 0.3.2. The marker is the documented
escape hatch (BUILD-SYSTEM.md section 7).
Both gates clean: verify-fork-versions reports no violations,
sync-versions --check reports no gcc16 drift.
The fork was an unmapped tree -- verify-fork-versions.sh reported
'libc NOT-MAPPED'. Register it properly so it is governed like every other
Cat 2 fork rather than sitting outside the checks:
- local/fork-upstream-map.toml: libc -> rust-lang/libc 0.2.189, snapshot
mode (vendored from the registry, so its history is unrelated to
upstream's), with the temporary status noted inline.
- verify-fork-versions.sh: src/unix/redox/mod.rs added to the declarative
expected-differ list, so the content check keeps verifying the rest of
the tree instead of being blanket-skipped.
- local/docs/VENDORED-LIBC-FORK.md: what the fork adds, the relibc source
and evidence for every symbol, why the values come from relibc rather
than Linux (Redox's idtype_t is c_int where glibc uses an enum), and a
five-step retirement procedure.
- local/AGENTS.md: listed in the fork table, marked temporary.
Kept vendored for as long as it is required. The gap is upstream-
reportable and belongs in the libc crate.
local/sources/libc is libc 0.2.189 with src/unix/redox/mod.rs extended to
expose the waitid surface relibc already implements:
- idtype_t (= c_int, as relibc defines it)
- P_ALL / P_PID / P_PGID
- CLD_EXITED / KILLED / DUMPED / TRAPPED / STOPPED / CONTINUED
- extern fn waitid(idtype_t, id_t, *mut siginfo_t, c_int) -> c_int
All of it is real in relibc -- src/header/sys_wait/mod.rs defines the
types and constants, and `nm libc.a` shows `T waitid` -- but the libc
crate's Redox bindings never exposed any of it, and still do not as of
0.2.189. Any crate calling waitid therefore cannot build for
x86_64-unknown-redox:
error[E0531]: cannot find unit struct, unit variant or constant
`CLD_EXITED` in crate `libc`
which breaks nix, and through it ctrlc and rustc's bootstrap tooling --
the last thing blocking rust-native.
Values and types come from relibc, not from Linux. Every non-Redox target
is byte-for-byte upstream 0.2.189, so host builds are unaffected. Wired
into the rust workspace via [patch.crates-io]; the fork type-checks for
x86_64-unknown-redox.
Upstream-reportable: this gap belongs in the libc crate.
Putting it in plain CXXFLAGS also handed it to the Redox cross g++, whose
C++ probe then failed during the freestanding stage, before libstdc++
exists:
configure: error: C++11 is required
libcody -- where the char8_t failures occur -- is compiled by
CXX_FOR_BUILD (the host g++ 16), so CXXFLAGS_FOR_BUILD is the correct
knob and the cross compiler is left alone.
rustc_llvm compiles llvm-wrapper/*.cpp, which include
"llvm/Config/llvm-config.h". Those headers ship in the .dev package, and
rust-native listed only llvm-native and llvm-native.runtime, so the build
failed with
LLVMWrapper.h:6:10: fatal error: llvm/Config/llvm-config.h:
No such file or directory
even though the header was staged at
llvm-native/target/<triple>/stage.dev/usr/include/. recipes/dev/rust
declares the equivalent llvm21.dev for the same reason.
Latent because rust-native was commented out of the config and had never
been built.
gcc13
The host compiler is now GCC 16, which defaults to C++20
(__cplusplus 202002L). C++20 changed u8"" literals from const char[] to
const char8_t[], and GCC 13's libcody -- its module mapper -- uses them
throughout, so the build collapsed with ~100 diagnostics like
error: invalid conversion from 'const char8_t*' to 'const char*'
in libcody/{buffer,client,server}.cc. GCC 13's sources are C++17; build
them at that standard. Not a workaround -- it is the dialect this
release was written against.
rust / rust-native
nix 0.30.1 is incompatible with the resolved libc 0.2.178: it declares
type SaFlags_t = libc::c_ulong while libc now has sigaction.sa_flags and
the SA_* constants as c_int, so rustc's bootstrap tooling failed with
error[E0308]: expected `u64`, found `i32` nix/src/macros.rs:72
error[E0308]: expected `i32`, found `u64` nix/src/sys/signal.rs:808
nix 0.31 fixed it by flipping the default to c_int. ctrlc moves itself
(3.5 requires nix "0.31"), but in-tree miri pinned 0.30.1 and kept the
broken version in the graph, so both are moved forward -- update and
adapt rather than pinning libc back, per the
Most-recent-upstream-when-building rule. Both crates were already in the
offline registry cache.
These surfaced only because gcc-native/rust-native were restored to the
config; neither had been building.
Three defects that were latent until GCC 14+ made implicit declarations
and pointer-type mismatches errors. None was a missing implementation --
in every case the code existed and only the declaration was wrong.
libinput
Carried its own bundled libudev.h that shadowed the real one from the
libudev recipe, which it already declares as a dependency. The bundled
copy lacked udev_device_get_sysattr_value(), so udev/libinput-device-
group.c got an implicit declaration and then an int-to-pointer
assignment. The real header is a strict superset -- nothing is declared
in the bundled copy that the real one lacks -- so the bundled file is
dead code that shadows a real implementation, which
LOCAL-FORK-SUPREMACY-POLICY.md Rule 4 requires removing.
linux-kpi
ieee80211_register_rx_handler() is fully implemented in
src/rust_impl/mac80211.rs as #[no_mangle] extern "C", and
ieee80211_rx_drain()'s own doc comment refers to it, but it was never
declared in c_headers/net/mac80211.h. Declared it.
redbear-iwlwifi
- rb_iwlwifi_bridge_register_rx() is used ~1800 lines before its
definition with no forward declaration. Added one at file scope.
- bridge_rx_callback was declared here as taking void *hw, while its
Rust definition in src/bridge/callback.rs takes *mut Ieee80211Hw and
linux-kpi's RxCallback type expects struct ieee80211_hw *. The C
declaration was simply wrong; corrected to match the implementation.
All three cook clean.
libpng
contrib/libtests/pngvalid.c calls feenableexcept(), a glibc extension
relibc does not provide, and GCC 14+ makes the implicit declaration an
error. It is a test program, so build it the way AGENTS.md
§ CONVENTIONS already prescribes for cross builds -- '--disable-tests'.
The library is unaffected; only check_PROGRAMS is skipped, and those
binaries cannot run on the build host regardless.
zsh
zsh 5.9 probes for the termcap symbol arrays with
char **test = boolcodes; puts(*test);
and ncurses declares boolcodes as 'const char * const *'. GCC 14
promoted -Wincompatible-pointer-types to an error, so the probe stopped
compiling, configure concluded boolcodes=no, HAVE_BOOLCODES was left
undefined, and Src/Modules/termcap.c fell back to defining its own
array -- colliding with the header:
termcap.c:45: error: conflicting types for 'boolcodes'
The probe uses a bare shell variable, not an ac_cv_ cache entry, so
there is nothing to override; restoring the pre-GCC-14 severity is what
lets it reach the right answer. Scoped to this recipe so the rest of the
tree keeps the stricter default.
Both cook clean.
uutils / onig_sys
oniguruma guards its alloca.h include on the autoconf macro:
#if defined(HAVE_ALLOCA_H)
# include <alloca.h>
#endif
onig_sys is compiled by the `cc` crate, so no configure ever runs and
nothing defines it. Under GCC 14+ the resulting implicit declaration is
an error, so uutils failed at
regint.h:271: error: implicit declaration of function 'alloca'
relibc does ship <alloca.h>, so declare it in the cookbook's C flags.
This asserts a fact about the sysroot rather than silencing a warning,
and is what a cross-build environment is expected to supply for sources
that have no configure step. Packages whose own configure defines it to
1 are unaffected -- identical redefinitions are not diagnosed.
netutils
Declares `libredox = "0.1"`, a version string, so cargo resolved
libredox and its transitive redox_syscall from crates.io instead of the
forks. With the forks now at 0.1.19 / 0.9.1 the crates.io side is not in
the offline cache and the build died with
failed to download `redox_syscall v0.9.0`
Caused by: attempting to make an HTTP request, but --offline was
specified
local/AGENTS.md 'Local fork dependency rule (ABSOLUTE)' prohibits
version strings for crates that have a local fork, for exactly this
reason -- a second copy of the crate in the graph gives mismatched
types, and offline builds cannot resolve it at all. [patch.crates-io]
now redirects the direct and transitive resolutions onto the forks.
Both cook clean.
Three GCC 16 gaps found by the redbear-full build.
-fhardened (seatd and other meson recipes, 24 errors)
-fhardened is a host-glibc hardening bundle x86_64-unknown-redox cannot
implement, but GCC accepts it on the command line, so meson's
cc.has_argument('-fhardened') probe answers YES and meson adds it to
every compile. GCC then refuses it for real:
cc1: error: '-fhardened' not supported for this target [-Werror]
Note the tag is [-Werror], not [-Werror=hardened] -- it is an
unconditional warning, so -Wno-hardened does not silence it (tried, and
it did not). The flag has to be cancelled instead; -fno-hardened does
that cleanly and the cookbook's flags are appended after the project's
own, so it wins. Nothing is weakened: the compiler is telling us the
option is inert on this target.
termcap (two independent defects, both latent until now)
1. Makefile.in hardcoded 'CFLAGS = -g' and has no @CFLAGS@ substitution
at all, so nothing configure resolved ever reached the compiler --
including the toolchain's default C dialect. termcap is pre-ANSI
code, so being compiled as GCC 16's default C23 failed at once with
'too many arguments to function malloc; expected 0, have 1'.
Substituting @CFLAGS@ is what a normal autotools Makefile.in does.
2. With CFLAGS flowing, the remaining errors were implicit declarations
of strlen/memcpy/exit/write, which GCC 14+ makes errors regardless of
-std. Cause: autoconf 2.70+ removed AC_HEADER_STDC, so STDC_HEADERS
is never defined and termcap.c/tparam.c took their pre-ANSI branch,
declaring 'char *malloc ();' instead of including <stdlib.h>.
Autoconf's guidance on dropping AC_HEADER_STDC is to assume those
headers exist, which holds for every target Red Bear builds.
pam-redbear
Cargo.lock missed by the earlier sweep; regenerated for the 0.3.2 fork
versions.
termcap and seatd now cook clean.
The unique-temp-name fix was treating symptoms. The actual defect is
structural: run_parallel_cook documents the invariant
'each recipe builds in its own target/stage/sysroot'
and that invariant is false. dep_levels() keys on the package NAME, so a
recipe's optional-package variants -- llvm-native, llvm-native.dev,
llvm-native.runtime -- are distinct units with no dependency between
them. They therefore land in the same level and cook concurrently while
sharing one target/<triple>/ directory, because build/, sysroot/ and the
stage* dirs are all derived from the recipe directory, not the package
name.
create_dir_clean() on the shared build/ then wipes a sibling's tree
mid-compile:
ninja: error: failed recompaction: No such file or directory
which is the error the earlier parallel builds kept producing and which
unique temp names could never have fixed -- build/ is a real, shared,
destructively re-created directory, not a staging path. It is also why
llvm-native cooks clean in isolation but failed in every parallel build,
and why that failure was misread as a porting gap serious enough to
exclude the package from the config.
Make the recipe DIRECTORY the unit of mutual exclusion. Distinct recipes
still cook fully in parallel; only siblings serialise, and that costs
almost nothing because one cook already populates every stage dir for
the recipe -- the siblings that follow find their work done and return
cached. It also stops LLVM being built three times over.
Residual, not addressed here: recipes joined by [source] same_as (e.g.
llvm-native -> llvm21) share a source tree. That is read-only during
cook, but a concurrent fetch/patch of the shared source would be a
separate race.
gettext failed to link against the GCC 16 toolchain with
ld: libc.a(...rcgu.o):(.bss.error_message_count+0x0): multiple
definition of `error_message_count'; libgrt.a(libgrt_a-error.o):
first defined here
Root cause is a cross-compile artefact, not a compiler change. gnulib's
check for a working error() is a RUN test, so cross-compiling reports
'checking for working error function... guessing no' and turns on
GNULIB_REPLACE_ERROR. Two things then go wrong at once: consumers are
redirected to rpl_error, and gnulib's own error.c -- listed in
am__objects_5 with no GL_COND_OBJ_ERROR guard -- still defines the
unrenamed error_* globals, which collide with relibc's.
relibc genuinely implements error(), error_at_line() and all three
globals (verified with nm). Two coordinated fixes:
- gl_cv_func_working_error=yes in the recipe. Stating the answer a run
test cannot reach while cross-compiling is the standard autoconf
mechanism, and is exactly what the neighbouring ac_cv_/gt_cv_ entries
already do for the same reason. Consumers now call relibc's error()
and no rpl_error reference remains.
- Guard gnulib's error.c on HAVE_ERROR, which configure already defines
as 1 -- upstream gnulib later made this module conditional on the
system lacking error(); this snapshot computes the right answer and
does not act on it. Without this the definitions still collide, since
relibc is Rust and one codegen unit carries several symbols, so
referencing any of them drags the whole object in. glibc escapes this
only by giving each its own object file.
gettext cooks clean. Patch generated by diff, applies at --fuzz=0.
Concurrency
-----------
Package variants of one recipe (llvm-native, llvm-native.dev,
llvm-native.runtime) share a single target/<triple>/ directory and are
cooked concurrently by the cook_jobs thread pool, but every staging path
under it had a fixed name -- stage.tmp and sysroot.tmp. The variants
therefore raced: one renamed or removed the shared directory while a
sibling was still writing into it.
Canonicalize stage dir failed at '.../stage.tmp': No such file or directory
Renaming failed from '.../sysroot.tmp' to '.../sysroot': File exists
llvm-native cooks clean on its own -- verified, zero errors, all three
variants published -- but failed in every parallel build for this
reason. It was never a compile error, which is what the earlier
'C++/pthread header gaps' note in the config misattributed.
Both stage.tmp sites and the sysroot site now go through one
unique_tmp_dir() helper. A pid alone cannot disambiguate (the pool is
threads in one process), so a process-wide counter supplies uniqueness.
Config
------
Restore gcc-native, llvm-native and rust-native to redbear-full.
gcc-native was set to "ignore" and the other two were commented out as
'not needed for greeter proof'. Both forms are forbidden by AGENTS.md
ABSOLUTE RULE -- NEVER DELETE, NEVER IGNORE, NEVER COMMENT OUT, and by
local/AGENTS.md 'No build-excluded until ported packages': a package
that does not build gets ported, not excluded. llvm-native is required,
not optional -- it supplies the host LLVM dev tree that libclc and
Mesa's iris/radeonsi CLC path need.
Remaining hunks from the doc pass: local/AGENTS.md and the
legacy-superseded SUPERSEDED.md still cited the driver-manager
ASSESSMENT-2026-07-22 / D5-AUDIT evidence files and the archived
migration plan as if they were openable. Cargo.lock picks up the
0.3.1 -> 0.3.2 Cat 0 and installer versions.
argp-parse.c and argp-help.c wrap the whole alloca-declaration block in
'#ifndef __GNUC__', so the header is never included when building with
GCC -- the code relied on GCC historically providing an implicit
declaration. GCC 14 promoted -Wimplicit-function-declaration to an error
and C23 removed implicit declarations, so the GCC 16 cross toolchain
fails:
argp-parse.c:1227:36: error: implicit declaration of function 'alloca'
argp-help.c:1329:35: error: implicit declaration of function 'alloca'
configure already sets HAVE_ALLOCA_H 1 and relibc's <alloca.h> defines
alloca(size) as __builtin_alloca(size), which is what GCC wants. Honour
HAVE_ALLOCA_H before consulting __GNUC__; non-GCC paths are untouched.
Patch generated by diff against pristine source, applies at --fuzz=0,
and the recipe cooks clean. Second opportunistic C23-era fix under the
gnu17 migration, after libiconv.
The libredox 0.1.19 / redox_syscall 0.9.1 bump left 45 recipe lockfiles
pinning libredox 0.1.18+rb0.3.1 and redox_syscall 0.9.0+rb0.3.1. The
cookbook builds with --locked, so every affected recipe died with
error: cannot update the lock file .../Cargo.lock because --locked was
passed to prevent this
which is what took out redox-driver-sys -- and with it every Red Bear
driver -- during the redbear-full build. Regenerating the fork lockfiles
was not enough; the recipes that consume the forks as path deps carry
their own. This is step 6 of local/docs/FORK-BUMP-PATCHING-POLICY.md
applied to the recipe layer.
Also drop the hardcoded GCC version in recipes/libs/libstdcxx-v3: the
literal include/c++/13.2.0 stopped resolving the moment the cross
toolchain moved to 16.1.0, leaving -I pointing at a directory that does
not exist. Now resolves the newest installed C++ header directory and
fails loudly if there is none. Same failure class as the hardcoded
13.2.0 in mk/prefix.mk.
Note: a few recipe-level Cargo.lock files (redox-driver-pci, cpufreqd,
redbear-acmd/-ecmd/-ftdi) sit beside a recipe.toml whose [source] is
path = "source", so they are not build inputs; redox-driver-pci's even
references a redox-driver-core/Cargo.toml that does not exist. They are
left alone rather than given meaning they do not have.
redox-driver-sys now cooks clean.
Two related races on recipes/<r>/target/<target>/sysroot, hit by
llvm-native during a -j 20 redbear-full build:
repo: failed to build: Renaming failed from '.../sysroot.tmp' to
'.../sysroot': File exists (os error 17)
llvm-native, llvm-native.dev and llvm-native.runtime are package
variants of one recipe and share that target directory. The cook_jobs
pool runs them as concurrent threads in a single process, so:
1. Shared staging path. Every variant used the same '<sysroot>.tmp', and
create_dir_clean() at the start of the staging block would wipe a
sibling's half-populated tree while it was still extracting pkgars
into it. Staging is now per-call, named from an atomic counter (a pid
would not disambiguate -- the pool is threads, not processes).
2. TOCTOU on the publish. The '!deps_dir.is_dir()' guard is checked long
before the rename, so all variants can pass it and then race; rename(2)
returns EEXIST/ENOTEMPTY once a winner has published a non-empty
directory, and the losers failed the whole recipe. Losing is harmless
-- every variant populates from the same recipe's dep set, so the
winner's tree is equivalent -- so the losers now discard their staging
and use it. The destination is deliberately not removed first, since a
concurrent cook may already be reading it.
Round 18's N22 'stale-doc removal' deleted three docs on the stated
premise that they had 'no references anywhere in the repo'. That premise
was wrong for two of them, and SUPERSEDED-DOC-LOG.md's recorded
absorption destinations for those two do not exist:
- CUB-PACKAGE-MANAGER.md was said to be absorbed into a 'redbear-cub
recipe README.md' and NETWORKING-IMPROVEMENT-PLAN.md section 8.2.
Neither exists -- there is no cub README under local/recipes/system/cub,
and that plan has no package-manager section (its 'cubic' matches are
TCP congestion control). README.md meanwhile links the doc from its
Documentation list and names cub in six places, so this left a headline
component with no documentation at all.
- BLUETOOTH-IMPLEMENTATION-PLAN.md was said to be merged into
NETWORKING-IMPROVEMENT-PLAN.md section 3.x. That file contains three
passing mentions of Bluetooth, not a 703-line plan. local/AGENTS.md,
docs/README.md and docs/07 all still list it as a first-class subsystem
plan, and AGENTS.md forbids treating Bluetooth as secondary.
Both restored from aa480f7ca3^ and their SUPERSEDED-DOC-LOG entries
retracted with the reason. USB-VALIDATION-RUNBOOK.md's supersession is
genuine -- USB-IMPLEMENTATION-PLAN.md carries the runbook as section 6.x
test procedures -- so it stays removed and its one reference now points
there.
Also de-dangled references to docs the authorised 2026-07-27
consolidation (092d1b39c3) removed but which canonical docs still cited
as openable: the driver-manager ASSESSMENT-2026-07-22 and D5-AUDIT
evidence files and the archived migration plan, across eight documents.
They now name what they were and where the supersession is recorded.
Remaining unresolved references are upstream KWin's vendored README
pointing at upstream's own CONTRIBUTING.md, which is deliberately not
touched.
verify-fork-versions.sh reads the 4th column of fork-upstream-map.toml
and skips the content check for forks marked 'diverged', with a WARN.
verify-fork-functions.sh had no notion of mode and hard-failed every
fork, so kernel (30), bootloader (5) and installer (2) blocked every
canonical build for drift the map itself records as accepted, with
comments saying a full rebase is later work.
Both verifiers now read the same source of truth. Diverged forks are
reported and counted as warnings; every other fork still gates. This
turned a 5-fork / 43-function hard failure into 2 real findings, which
are fixed in the accompanying relibc and base commits.
Cargo.lock in seven forks still named libredox 0.1.18+rb0.3.1 and
redox_syscall 0.9.0+rb0.3.1. Cargo rewrites them on first build, which
then trips the dirty-source gate mid-run. Regenerated offline and
committed so fingerprints reflect committed state.
New local/docs/FORK-BUMP-PATCHING-POLICY.md, wired into AGENTS.md,
local/AGENTS.md and docs/README.md. Core rule: a version bump is a
REBASE, never a REPLACEMENT.
Written from the libredox 0.1.19 incident, which hit three failures at
once -- wholesale replacement that dropped the acpi re-export,
F_DUPFD_CLOEXEC, the mandated authors entry and the Single-Repo
repository URL; a version-named branch that also tripped the build's
fork-branch gate; and a stale fork-upstream-map.toml that failed
verify-fork-versions.sh with a fake-label violation. Covers the vendored
recipe-fork mirror image (metadata moves, build input does not -- how Qt
shipped 6.11.0 against a 6.11.1 recipe), patch handling during a bump,
and toolchain bumps as version bumps.
Also fixes the two bookkeeping gaps that failed this build:
- local/fork-upstream-map.toml: libredox 0.1.18 -> 0.1.19, never updated
when the fork was bumped.
- verify-fork-versions.sh: record redoxfs's legitimate divergence in the
declarative allowlist the script already provides for libredox, with
the originating commit for each file -- a936d00 (Red Bear, Vec from
alloc for no_std bootloader builds) for filesystem.rs and record.rs,
852a971 (Red Bear, RecvFd EOPNOTSUPP) for mount/redox/mod.rs, and
d807dd3 (upstream symlink fix imported ahead of the 0.9.1 tag) for
mount/redox/scheme.rs. Documented rather than bypassed with
REDBEAR_SKIP_FORK_VERIFY.
Docs:
- Baseline was stated as 0.3.1 across the canonical set while the branch,
Cat 0/1 crates and every Cat 2 fork are 0.3.2. AGENTS.md also cited a
sources/redbear-0.3.1/ archive that does not exist; the only archive
present is sources/redbear-0.1.0/. Versioning examples now match the
forks as they actually stand (redoxfs/syscall 0.9.1, libredox 0.1.19).
- Repaired 18 instances of 'immutable archived' across 8 documents, where
a global find/replace had turned sync/synced/archived into that phrase
and produced ungrammatical text ('never auto-immutable archived',
'### Source immutable archived').
- Settled the apply-patches.sh contradiction empirically. Both sides were
wrong: the GROSS WARNING blocks (x5) described it as routine
patch-linking, and SCRIPT-BEHAVIOR-MATRIX.md said build-redbear.sh
'never invokes' it. It is invoked at build-redbear.sh:487, but only to
auto-repair a failed verify-overlay-integrity.sh check.
- Dropped the dangling reference to a local/AGENTS.md section
'NO OVERLAY-STYLE PATCHES — SCOPED POLICY' that does not exist.
Build system:
- mk/prefix.mk hardcoded 13.2.0 in the limits.h removal, which silently
no-ops after a toolchain upgrade and leaves the conflicting header.
Version-globbed.
- Parameterized GCC_RECIPE so the from-source toolchain path is not
pinned to gcc13.
- The three cstdlib strtold seds were not idempotent -- the shipped GCC
13 toolchain carried that comment block 17 times from repeated
'make prefix' runs. Each is now guarded.
The gitlink referenced 4398964, the tip of a stray 'bump-0.1.19' branch.
That branch violated local/AGENTS.md BRANCH AND SUBMODULE POLICY (no
version-named branches) and, being a wholesale replacement of the fork
with upstream, had dropped committed Red Bear work: the redox_syscall-
gated 'pub mod acpi' re-export, F_DUPFD_CLOEXEC, the vasilito authors
entry required by 'Fork authorship attribution', and the
gitea.redbearos.org repository URL required by the Single-Repo Rule.
submodule/libredox now carries upstream 0.1.19 merged into the fork, so
both the upstream multiple-fds work and all Red Bear work are present.
Type-checks clean for x86_64-unknown-redox.
recipes/**/*.patch is gitignored, but 01_redox.patch is force-added and
tracked. Match that precedent so the patch wiring survives a clean
checkout -- recipe.toml lists it, so an untracked symlink would break
the build from scratch.
GCC 13.2.0 defaulted to gnu17 (__STDC_VERSION__ 201710L); GCC 16.1.0
defaults to gnu23 (202311L). The recipe tree is C17-era code, and C23
turns an empty parameter list from 'unspecified arguments' into 'no
arguments', which is a hard error against a real prototype.
Pin the cookbook's default C dialect to gnu17. This states the dialect
these sources were written against rather than suppressing a diagnostic,
and matches how the distributions handled the same GCC 14/15 transition.
Packages migrate to C23 as they are touched; the pin is dropped when the
tree is clean. A per-recipe -std= still wins, being appended after. C++
is deliberately NOT pinned -- kwin needs C++23, which is the entire point
of the GCC 16 upgrade.
Fix a real cookbook bug this exposed: CMAKE_CXX_FLAGS was built from
CFLAGS, so the C dialect flag reached the C++ compiler and g++ reported
"'-std=gnu17' is valid for C/ObjC but not for C++" on every file. The
meson path already keeps c_args/cpp_args apart; CMake now matches.
CPPFLAGS still reaches both, which is what carries the sysroot includes.
First opportunistic C23 fix: libiconv's lib/loop_wchar.h declared
'extern size_t mbrtowc ();', conflicting with relibc's four-argument
prototype. That declaration exists only for platforms whose <wchar.h>
does not declare mbrtowc -- per its own comment, BeOS, which lacks
mbstate_t and #defines it -- and the very next line already tests
'#ifdef mbstate_t'. Moving it inside that guard keeps it where it is
needed and drops it where a real prototype is in scope.
libiconv now cooks clean against GCC 16.1.0.
The Redox target port applier claimed validation on 16.1.0 but its
idempotency probe used each block's longest line, which for three blocks
is generic upstream boilerplate. Against a pristine 16.1.0 tree that
silently skipped the libgcc target arms and BOTH crossconfig.m4 arms
(libgcc/config.host and crossconfig.m4 contain zero redox references, yet
the applier reported 'already present'), producing a half-ported tree --
the exact failure the script documents itself as preventing. Probe on the
longest redox-bearing line instead, matched whole.
Two port requirements the original extraction missed, both fatal:
- gcc/config/redox.opt.urls. GCC 16 requires a .opt.urls companion for
every .opt; s-options fails without it. Contents match what
regenerate-opt-urls.py emits for these two options, cross-checked
against the six upstream .opt.urls declaring the same pthread/rdynamic.
- libtool has no redox host. Upstream Redox gets shared libraries from
recipes/dev/libtool (a Redox-patched libtool 2.5.4-redox-9510) via
libtoolize during autoreconf, not from GCC's bundled libtool.m4. That
route does not apply to GCC 16, which bundles 2.2.7-era macros plus its
own ltgcc.m4. Without redox arms _LT_SYS_DYNAMIC_LINKER leaves
dynamic_linker=no, libstdc++ builds static-only, and the desktop stack
cannot link -- libQt6Core.so and every KF6 library carry DT_NEEDED
libstdc++.so.6. apply-libtool-redox.py registers the four arms that
matter, verbatim from the Redox libtool macros already in prefix/.
Result: x86_64-unknown-redox-gcc 16.1.0 with libstdc++.so.6.0.35 (SONAME
libstdc++.so.6, NEEDED libc.so.6 + libgcc_s.so.1 -- identical to the
13.2.0 library it replaces, exports a superset up to GLIBCXX_3.4.35).
std::ranges::to now compiles for the Redox target; GCC 13.2.0 fails the
same test, which is what blocked kwin's 16 affected files.
install-gcc16-toolchain.sh installs into all three locations a recipe can
resolve a compiler from -- including ~/.redoxer, which src/cook/script.rs
puts highest on PATH -- and is reversible with --restore. Its cstdlib
strtold patch is guarded; the mk/prefix.mk sed is not, and had applied
that block 17 times to the GCC 13 toolchain.
Both forks moved to the real upstream crate version, with in-house work
preserved deliberately rather than through upgrade-forks.sh's net-diff
(which squashes Red Bear commits into a single reapplied patch).
syscall 0.9.0 -> 0.9.1, via rebase. All 16 Red Bear commits replayed
individually so history and authorship survive; three obsolete label-only
commits dropped. Verified present afterwards: SYS_SETNS, SYS_CLOCK_SETTIME,
AcpiVerb::SetLpiHint, EnterS2Idle/ExitS2Idle, SetS3WakingVector, O_CLOEXEC,
SYS_SENDFD, SYS_OPENAT_WITH_FILTER, FullContextRegs, SYS_SYNCFS. Delta vs
upstream is purely additive: 348 insertions, 1 deletion across 9 files.
libredox 0.1.18 -> 0.1.19, via cherry-pick (a rebase aborted on the fork's
bulk "apply Red Bear patches" commit). Kept the two changes still unique to
us: demux() unwrap_or(u16::MAX) instead of .expect(), and Fd::ftruncate /
Fd::futimens taking &self. Dropped three in favour of upstream, which now
implements them at least as well: O_CLOEXEC handling, .gitignore/metadata,
and the bulk patch commit. Net delta is now 8 insertions / 3 deletions.
Pre-bump states kept at rb-backup/syscall-pre-0.9.1 and
rb-backup/libredox-pre-0.1.19 in the respective forks.
NOTE: neither fork branch is pushed yet - both rebases rewrote history, so
submodule/syscall and submodule/libredox need a force push, and the remote
tips must be confirmed to still equal the rb-backup commits first.
Applies the extracted port to an unpacked GCC tree: copies the 5
Redox-owned files, then inserts each redox arm at an anchored point.
Validated against a real gcc-16.1.0 tree (blake3
5f001609f662143ce9285cd740bd0acfeeaf7f13731b46fd1d9ebe620c5c340d).
Findings from that validation:
- GCC 16 already recognises redox in config.sub upstream, one fewer file
to patch than in 13.2.0.
- Two anchors moved since 13.2.0 and were re-derived: solaris folded into
the linux arm in crossconfig.m4, and the mingw32 targets were
consolidated in mkfixinc.sh.
- libgcc's riscv64 arm had been truncated during the original capture;
restored.
Two idempotency bugs found by comparing redox-line counts against the
13.2.0 reference rather than trusting "it ran clean":
- a substring probe matched the generic block's case label inside the
already-inserted aarch64/riscv64 label, silently skipping the second
crossconfig.m4 block;
- a first-line probe matched the aarch64 label inside CONFIG_GCC_OS,
silently skipping config.gcc's tm_file target arms, which would have
produced a tree that configures but never pulls in redox.h.
Now probes on the block's longest line, matched whole. config.gcc reaches
16/16 redox lines, matching the 13.2.0 reference exactly.
Verified for x86_64-unknown-redox: config.gcc tm_file arm incl. redox.h,
config.host xm_file, libgcc arm, crossconfig generic arm, mkfixinc arm,
gcc/config/redox.h, and the _GLIBCXX_USE_WEAK_REF define.
Re-running is a no-op. NOT YET BUILT: no compiler has been produced, and
gcc/configure plus libstdc++-v3/configure still need regenerating from
crossconfig.m4 with autoconf.
Latest upstream RELEASE tag is releases/gcc-16.1.0; '16.1.1' seen on distros
is a packaging/snapshot string, not an upstream release. Both
gcc-16.1.0.tar.xz and gcc-15.3.0.tar.xz confirmed reachable on ftp.gnu.org
(HTTP 206 on a range request). The Redox gcc fork carries no upstream
release tags, so the pristine base must come from ftp.gnu.org or
gcc-mirror.
Records the ordered next steps and marks them explicitly NOT STARTED, so the
extraction is not mistaken for a working port. The dominant cost is step 5 --
the full C++ tree rebuild forced by the libstdc++ ABI change -- not the
13-file port itself.
Groundwork for moving off GCC 13.2.0. Upstream redox-os/gcc has only
redox, redox-8.2.0 and redox-13.2.0, so there is no GCC 14+ with Redox
support to consume -- the port has to be carried by us.
Forced by KDE: KWin (16 files) and plasma-workspace (1 file) use C++23
std::ranges::to and both declare CMAKE_CXX_STANDARD 23. Verified the
current toolchain cannot satisfy that: the fork's libstdc++ has no
__cpp_lib_ranges_to_container and gcc/BASE-VER is 13.2.0, so there is no
hidden 14-ness to exploit. Backporting the call sites was rejected as the
costlier path -- it recurs every KDE release and diverges from upstream
KDE, against 'adapt to upstream, never the reverse'.
Measured surface: the whole Redox port is 13 files. Five are Redox-owned
(redox.h 36 lines, redox.opt 27 lines, three xm-redox.h) and are captured
verbatim under files/. The other eight are *-*-redox* case arms in
config.sub, gcc/config.{gcc,host,build}, libgcc/config.host,
libstdc++-v3/crossconfig.m4, os_defines.h and fixincludes/mkfixinc.sh,
captured with context in registration-hunks.txt. This is a textbook GCC
target port, not a compiler fork.
README records the apply procedure and the measured risks: libstdc++ ABI
change forces a full C++ tree rebuild; mk/prefix.mk currently DOWNLOADS the
toolchain from static.redox-os.org, so building our own is a permanent
ownership cost; relibc's cbindgen headers have a documented history of
fighting GCC and a newer one may reopen it; and mk/prefix.mk hardcodes
'13.2.0' in a path that must be parameterized.
Note gcc/configure and libstdc++-v3/configure also match 'redox' but are
GENERATED -- regenerate from crossconfig.m4, do not hand-edit.
The upgrade decision compared the newest upstream git TAG against $base,
which callers pass as the fork's Cargo.toml CRATE version. For several
Redox crates those namespaces are unrelated, so the comparison was
meaningless:
relibc git tags 0.5.0 / 0.6.0, but Cargo.toml AT tag 0.6.0 is 0.1.0,
and our fork is 0.2.5 -> reported '0.2.5 -> 0.6.0 upgrade'
when upstream master is 0.2.5, i.e. ALREADY CURRENT
libredox newest tag is v0.1.13, but upstream master is 0.1.19
Not cosmetic: upgrade-forks.sh consumes the result as --to=<ref> and does
'git reset --hard <ref>' before reapplying Red Bear commits as a net diff.
Acting on the relibc answer would have reset the fork onto an unrelated
lineage and reapplied our commits against it.
These forks are Cargo path deps with [patch.crates-io] and our label is
<upstream-version>+rb<branch>, so the CRATE version is the upstream
identity Cargo must satisfy -- compare crate-to-crate. Tag scanning
remains as the fallback for forks with no readable Cargo.toml.
Report after the fix:
syscall 0.9.0 -> 0.9.1 upgrade (tag 0.9.1 also exists)
libredox 0.1.18 -> 0.1.19 upgrade (master only; no matching tag)
relibc 0.2.5 ok (was a false positive)
redoxfs / redox-scheme / userutils ok
Known gap, documented at the call site: a fork whose crate version has no
matching tag (libredox) will make upgrade-forks.sh --to=<version> fail
loudly rather than reset onto a wrong ref -- the safe outcome. Threading
the upstream branch ref through as the rebase target is follow-up work.
New release branch per the release-branch model (operator decision;
local/AGENTS.md reserves branch creation to the operator).
sync-versions.sh, driven by bump-release.sh, rewrites:
- Cat 1 in-house crates -> version = 0.3.2
- Cat 2 upstream forks -> <upstream-tag>+rb0.3.2
Labels only; no fork source was rebased in this commit. bump-release.sh
reports these forks as having newer upstream tags, to be taken next:
relibc 0.2.5 -> 0.6.0
syscall 0.9.0 -> 0.9.1
libredox 0.1.18 -> 0.1.19
redoxfs and redox-scheme are already current. kernel, bootloader and
installer are 'diverged' in the fork map and stay report-only (manual
rebase); bootloader additionally has no merge-base with upstream.
kwin needs qtwaylandscanner_kde to run during the build. Its cmake offers
three paths (src/wayland/tools/CMakeLists.txt): a prebuilt binary via
QTWAYLANDSCANNER_KDE_EXECUTABLE, an in-place cross-compile via
ExternalProject, or a native build. With no executable supplied it took
the ExternalProject path, which inherits this recipe's cross CC/CXX/CFLAGS
and therefore compiled HOST code with the Redox toolchain:
/usr/include/qt6/QtCore/qsystemdetection.h:135:
#error "Qt has not been ported to this OS"
-- host headers, target compiler. Same host/target confusion as the
mesa-clc LLVM mislink, but inside an ExternalProject where QT_HOST_PATH
and KF6_HOST_TOOLING have no reach. Build it ourselves with the host
toolchain (the tools dir declares its own project() when it is top-level)
and pass it in: upstream's own first branch, no leakage. Host Qt6 is
6.11.1, matching the target Qt.
Bumps local/sources/relibc to pick up 'sys/un.h: define SUN_LEN'. KWin's
wl-socket.c uses that BSD/glibc extension and relibc did not define it.
Fixed in the fork rather than worked around in the recipe, per the
zero-tolerance stub policy; the prefix rebuilds automatically on the next
canonical build.
kwin compiles further; the remaining failure has moved into the native
qtwaylandscanner_kde sub-build (host/target flag leakage), not the target
sources.
killer and dialoghelper both include <private/qtx11extras_p.h> unguarded
and call QX11Info / XCB_CURRENT_TIME behind a RUNTIME platformName()==xcb
check that is always false on a Wayland-only session. Note src/main.cpp
does this CORRECTLY -- #if KWIN_BUILD_X11 around both the include and
every use -- so the guard is upstream's own convention and these two
helpers simply were not updated. Core kwin needed no change.
The missing private header also explains a misleading second symptom: on
failing to find it the compiler fell back to the HOST /usr/include/qt6 and
reported 'Qt has not been ported to this OS', which looks like an
unrelated toolchain fault but is the same missing header.
kcm_kwin4_genericscripted includes QUiLoader from qttools, which is not
ported. Dropping only the Qt::UiTools link left the include behind, so the
whole target is gated. It is the settings dialog for scripted effects; the
effects themselves are unaffected. Remove once qttools lands.
kwin now gets past cmake configure into compilation for the first time.
nightlight: TEMPORARY DEBT, same shape as systembell. KNightTime is used
by exactly one plugin (src/plugins/nightlight). find_package(KNightTime
CONFIG) is not itself REQUIRED -- set_package_properties(TYPE REQUIRED)
plus feature_summary(FATAL_ON_MISSING_REQUIRED_PACKAGES) is what aborts.
Correct KNightTime source, verified and recorded at the call site:
https://download.kde.org/stable/plasma/6.7.2/knighttime-6.7.2.tar.xz
blake3 27b06ec4545f732d0c44934b2a3d6e9359bd5e90e94627377accf2b69725d677
It is a PLASMA component (versioned 6.7.x alongside kwin), NOT a
Framework. The frameworks URL is a trap: invent.kde.org answers HTTP 200
with an HTML error page for a nonexistent project, so a naive fetch yields
a 13KB 'tarball' that only fails later at extraction.
Porting it is deliberately not attempted here: KNightTime itself needs
Qt6Positioning and KF6Holidays, neither of which has a recipe in-tree --
a three-package chain for colour-temperature shifting. Port those two,
then knighttime, then drop the two nightlight seds.
Qt::UiTools: the top-level component list was already stripped, but the
generic scripted-effect KCM links the target directly, so cmake still
failed with 'Target kcm_kwin4_genericscripted links to Qt::UiTools but the
target was not found'. That is the only target_link_libraries reference.
kwin's CMakeLists issues find_package/pkg_check_modules REQUIRED for
several packages that are in the config and built but were never declared
as deps, so they were never staged into kwin's sysroot: libxcvt,
libdisplay-info, kglobalacceld, libinput, lcms2. Audited the CMakeLists
for REQUIRED names and cross-checked against recipes that exist, rather
than adding them one failed configure at a time.
KF6_HOST_TOOLING must point at the HOST's system KF6 (/usr/lib/cmake), as
konsole already does. src/wayland/tools needs a native Qt/KF6 prefix;
pointing it at build/qt-host-build instead fails differently, because that
tree carries Qt host tooling but no KF6, and KF6AuthConfig /
KF6KCMUtilsConfig then fail their include().
systembell: TEMPORARY DEBT, narrowly scoped and documented at the call
site. It is the only consumer of Canberra in KWin, yet
find_package(Canberra REQUIRED) is ungated, so one optional audible-bell
plugin blocks the whole compositor. The in-tree WIP libcanberra recipe
depends on gtk3 and is itself marked 'no audio backend supported'; a local
recipe using --disable-gtk3 plus the null backend is the intended fix.
Visual bell and every other effect are unaffected.
.config pinned COOKBOOK_MAKE_JOBS=4. config.rs reads that variable from
the environment into cook_opt.jobs, and cook_build.rs exports it to every
recipe's build script as its -j value; mk/repo.mk passes no --jobs flag,
so the pin was authoritative. Every recipe therefore compiled with -j4 no
matter what -j build-redbear.sh was given, capping a 24-core host at ~12
concurrent compiles through Qt, KF6 and Mesa.
Unset, it derives from -j (default available_parallelism()). Re-add only
to deliberately clamp per-recipe compiles BELOW -j.
KWin does an unconditional find_package(Vulkan REQUIRED), and CMake's
FindVulkan needs BOTH Vulkan_INCLUDE_DIR and Vulkan_LIBRARY. Mesa already
builds the Vulkan drivers (libvulkan_intel/_radeon/_lvp) but an ICD is not
the API surface a consumer links against, so kwin could not configure.
vulkan-headers: header-only, but VulkanHeadersConfig.cmake is GENERATED at
install time rather than shipped in the tarball, and Vulkan-Loader
hard-requires it -- a hand copy of include/ satisfies FindVulkan and then
fails the loader. Run upstream's cmake install instead.
vulkan-loader: one real port. vk_loader_platform.h gates the whole POSIX
arm (DIRECTORY_SYMBOL, the dlopen wrappers, manifest search) on an OS list
that predates Redox, so the build collapsed with 'DIRECTORY_SYMBOL'
undeclared. Redox provides dlopen/dlsym and POSIX paths via relibc, so it
belongs in the same arm as Linux; that header is the only file under
loader/ doing OS detection. WSI backends are left off: Red Bear is
Wayland-only and the compositor talks to Mesa's ICDs directly.
Both shadow the untested recipes/wip/libs/graphics/{vulkan-headers,
libvulkan} via the local-over-WIP mechanism, per the WIP ownership rule
that the shipping version lives in local/recipes/.
Verified: kwin now reports
-- Found Vulkan: .../sysroot/lib/libvulkan.so (found version 1.4.321)
kwin also gains its missing kf6-knewstuff dep -- its
find_package(KF6 COMPONENTS NewStuff) is REQUIRED, so without the dep the
framework was never staged into kwin's sysroot.
qt-sysroot.sh: Qt installs QML modules under <prefix>/qml, KDE under
<prefix>/lib/qml, and ecm_find_qmlmodule() only searches the KDE root. A
REQUIRED Qt module was therefore reported missing even though its recipe
staged it correctly (plasma-framework aborting on
Qt5Compat.GraphicalEffects) while every org.kde.* module resolved fine.
Bridge the two roots with relative symlinks, never clobbering a real KDE
module of the same name.
plasma-framework: kf6-kwindowsystem is built KWINDOWSYSTEM_X11=OFF, so
KX11Extras and KWindowInfo do not exist, yet core translation units
reference them. Every such call already sits behind a runtime
KWindowSystem::isPlatformX11(), which is always false here, and the
package already ships some #if HAVE_X11 sites -- this finishes the job
upstream started. Done in Python, not sed: the transform needs brace
matching, and an if/else chain must keep its ELSE body (appletpopup.cpp
sets the Wayland surface role there; wrapping the whole chain would have
deleted the Wayland path). Also guards the unconditional <xcb/xcb.h>
include and drops BlurEffectWatcher's QAbstractNativeEventFilter base,
whose only override is itself X11-guarded, leaving the class abstract.
Pin WaylandScanner_EXECUTABLE to the host tool for the same reason breeze
needed it.
kf6-knotifications: the range-comment sed had an UNANCHORED start address
and an anchored end, so on re-runs it matched the '#if (NOT APPLE ...'
it had produced itself while '#endif()' no longer matched -- the range
ran to END OF FILE, commenting a little more of CMakeLists.txt on every
rebuild until install(FILES ...) lost its closing paren. Anchor the start
so it cannot match its own output, and drop the companion
'sed 127,137 s/^#*//' hack that existed only to undo the damage.
Four distinct ways the cross build reached for the wrong thing:
mesa-clc: 'unset LDFLAGS' left only /usr/lib on the link path, so the
HOST libLLVM won over llvm-native. Arch-family builds use
-DLLVM_LINK_LLVM_DYLIB, so libLLVM re-exports libstdc++ symbols under its
own version node; mesa_clc then recorded std::string::reserve@LLVM_21.1,
which no llvm-native build provides. When it instead resolved the host
libLLVM at runtime, clang derived its resource dir from the HOST install,
and with host clang 22 beside an llvm-runtime 21.1 the directory
/usr/lib/clang/21 does not exist, so every OpenCL compile died with
"'opencl-c-base.h' file not found" -- nowhere near the cause. Put
llvm-native back on the link path with a matching -rpath, and pin the
staged tools' RUNPATH to this recipe's own sysroot. Also wipe build-clc
before meson setup: re-running setup on a configured dir reinterprets -D
flags as option CHANGES and aborts on any option the old configuration
lacked ("Unknown option: mesa-clc").
breeze: kconfig_compiler_kf6 resolved to the cross-compiled Redox binary,
which the host cannot execute ('cannot execute: required file not found'
is ENOENT on the ELF interpreter). Point at the host tool.
kde-cli-tools: installs to KDE_INSTALL_FULL_BINDIR, an ABSOLUTE /usr/bin.
'cmake --install --prefix' only re-roots relative destinations, so cmake
wrote straight into the BUILD HOST's filesystem and only file permissions
stopped it. Use DESTDIR, which re-roots absolute paths too. kstart is
X11-only (Qt private X11 interop header) and cannot work without an X
server, so exclude it as kdesu already is.
sddm: QML_INSTALL_DIR fell back to 'qmake -query QT_INSTALL_QML', i.e.
the HOST Qt, so SddmComponents installed into the host build tree. Every
greeter theme does 'import SddmComponents 2.0', so this broke the login
UI at runtime with no build-time error.
polkit: dbus-1.pc's system_bus_services_dir comes back sysroot-prefixed
under a cross build, dropping a bogus /mnt/... tree into the image.
warm-cargo-offline-cache.sh: builds run cargo with --offline --locked, so
resolution comes from the sparse-index CACHE, which only an online cargo
run refreshes. A lockfile can pin a version whose .crate is already
downloaded while the index cache does not list it, producing
error: failed to select a version for the requirement quinn = ^0.11.1
(locked to 0.11.11)
candidate versions found which didn't match: 0.11.9
on a dependency that is in fact present. 13 lockfiles were missing 42
crates this way. --check reports offending manifests without fetching.
test-sddm-virgl-qemu.sh: boots redbear-full on virtio-gpu-gl with
egl-headless so the guest takes the accelerated redox-drm -> Mesa (virgl)
-> Wayland path, captures the serial console and classifies each boot
marker independently rather than collapsing to pass/fail.
The extractor matched '(?:pub )?(?:async )?(?:unsafe )?fn \w+' and then
stripped only the 'fn ', leaving the visibility modifier inside the key.
So 'fn foo' and 'pub fn foo' were different keys, and 'pub(crate) fn' was
not matched at all. Merely changing a function's visibility made it look
deleted: base was reported as missing remove_dentry, which the fork
demonstrably still has, and the report printed nonsense like 'fn pub
socket'. The exclude files had accumulated duplicate entries ('foo' and
'pub foo') to work around this.
Compare bare names on both sides, and normalize the function half of each
exclude entry so existing files keep matching.