Operator decision 2026-08-05: "we will not have gcc 13." The cross toolchain has been GCC 16.1.0 since the port landed, but the build system still defaulted to GCC 13 in three places and nothing recorded the move. Build system: - mk/prefix.mk: GCC_RECIPE?=gcc13 -> gcc16. - mk/prefix.mk: the HOSTED_REDOX package rule derives its names from $(GCC_RECIPE) instead of hardcoding gcc13.pkgar / gcc13.cxx.pkgar. static.redox-os.org publishes no gcc16 package, so that path now fails at download. Deliberate: a loud failure beats a wrong compiler. - build-redbear.sh: refuse to build on a non-GCC-16 toolchain. This is the one that mattered on a Linux host. `make prefix` unpacks upstream's gcc-install.tar.gz, which IS GCC 13.2.0, and no make rule replaces it -- GCC 16 arrives only via install-gcc16-toolchain.sh. A fresh prefix therefore put you silently back on GCC 13, surfacing ~40 minutes later as a kwin C++23 failure. The guard checks all three locations (gcc-install, sysroot, ~/.redoxer/<target>/toolchain -- the last has highest priority) and names the two scripts to run. Docs: - New local/docs/TOOLCHAIN-GCC16.md: why the move (kwin/plasma-workspace need std::ranges::to), build/install/rollback procedure, the three locations that must agree, the tree-wide -std=gnu17 and -fno-hardened consequences, and the open libstdc++ float16-formatter gap that currently blocks the kwin link. - CHANGELOG, docs/README.md index and state summary, and the stale claim in NATIVE-TOOLCHAIN-WORKSTREAM.md that gcc13 "still builds the GCC 13 cross toolchain". Also corrects stale references found while auditing: - AGENTS.md described prefix/ as "Clang/LLVM"; it is GCC 16.1.0 + LLVM + Rust. - AGENTS.md cited local/reference/linux-7.0/ (tree is linux-7.1). - AGENTS.md's durable-patching example cited a mesa patch that does not exist; replaced with one wired in recipe.toml. (The first replacement used patch 03, which the changelog records as orphaned -- it targets a file removed from Mesa 26.1.4 upstream.) native_bootstrap.sh still installs gcc13/gcc13.cxx packages inside a Redox VM. Left alone: that is the deferred gcc-native workstream and no gcc16 package is published for Redox to point it at. Verified: bash -n clean; make -n prefix parses; guard accepts the current 16.1.0 toolchain in all three locations and rejects a stubbed 13.2.0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
8.7 KiB
Native Toolchain Workstream — gcc-native / rust-native
Status: DEFERRED. Explicit operator decision, 2026-08-03: "Treat
gcc-native/rust-native as a separate workstream, explicitly deferred by me, for
now."
Scope: local/recipes/dev/gcc-native/, local/recipes/dev/rust-native/.
Not deferred: binutils-native and llvm-native build and remain in
config/redbear-full.toml. llvm-native is required, not optional — it
supplies the host LLVM dev tree that libclc and Mesa's iris/radeonsi CLC path
consume.
Related: local/patches/gcc-redox-port/README.md,
VENDORED-LIBC-FORK.md, FORK-BUMP-PATCHING-POLICY.md,
LOCAL-FORK-SUPREMACY-POLICY.md.
What this workstream is
A toolchain that runs on Redox and targets Redox — gcc, cargo/rustc
executing inside the OS. Distinct from the cross toolchain in prefix/,
which runs on the Linux host and is what actually builds the distribution.
That distinction matters for prioritisation: the cross toolchain is done
(GCC 16.1.0, libstdc++.so.6.0.35, working std::ranges::to) and is what
compiled every other package. Nothing in the desktop path — Mesa/virgl,
Wayland, Qt6, KF6, SDDM — depends on the native toolchain.
Why it is deferred, honestly
Not because it is unimportant, and not for the reason the old config gave.
The previous exclusion said "suppressed: Redox C++/pthread header gaps; not
needed for greeter proof". That was wrong on both counts. llvm-native has no
header gap at all — it cooks clean in isolation, and only failed in parallel
builds because of a cookbook race on shared staging paths (fixed; see
src/bin/repo.rs recipe_dir_lock). A real build-system bug had been
misdiagnosed as a porting gap and used to justify excluding a required package.
Restoring these packages is how the twelve defects below were found at all —
including that redbear-iwlwifi had never compiled since the commit that broke
it.
The deferral is instead a scope judgement: making GCC build itself for Redox is a genuine porting project. Upstream Redox has only ever shipped GCC 8.2.0 and 13.2.0; nobody has done GCC 16 for this target. Every fix so far has revealed the next layer, and the remaining failures are header-model conflicts (GCC's internal headers vs relibc's, host vs target) that want someone working through GCC's cross-build header model as a whole rather than patching incrementally.
gcc-native — moved to GCC 16, twelve findings
The recipe now builds GCC 16.1.0 from local/recipes/dev/gcc16/source
(upstream 16.1.0 + local/patches/gcc-redox-port/), not GCC 13.
Why the move happened
Building GCC 13 with the GCC 16 cross compiler is three major versions of drift and is not a supported configuration. Three fixes landed before it became untenable:
| # | Defect | Resolution |
|---|---|---|
| 1 | char8_t. GCC 16 defaults to C++20, which changed u8"" from const char[] to const char8_t[]; libcody uses them throughout (~100 diagnostics) |
pin the C++ standard |
| 2 | libcody's configure contains #if __cplusplus > 201103 / #error "C++11 is required" — it rejects anything newer than C++11 |
-std=gnu++11, which also fixes #1 (no char8_t before C++20) |
| 3 | bit_AVX512PF / ER / 4VNNIW / 4FMAPS / PREFETCHWT1 undeclared — GCC 15/16 removed these macros for withdrawn ISA extensions, but GCC 13's cpuinfo.h needs them |
put GCC 13's own cpuid.h ahead of the toolchain's include path |
Then GCC 16 ICEd compiling GCC 13's own libstdc++:
libstdc++-v3/libsupc++/eh_call.cc:39:1: internal compiler error:
in gimple_build_eh_must_not_throw
An ICE is where flag-tweaking stops being a legitimate answer. Those three
fixes remain in recipes/dev/gcc13/recipe.toml, where they are correct for
that recipe. Note that the recipe no longer builds anything: as of 2026-08-05
this fork has no GCC 13 path at all — mk/prefix.mk defaults to
GCC_RECIPE?=gcc16 and build-redbear.sh refuses a non-GCC-16 toolchain. See
TOOLCHAIN-GCC16.md.
After the move to GCC 16
| # | Defect | Resolution |
|---|---|---|
| 4 | The same_as symlink source -> recipes/dev/gcc13/source survived the recipe edit, so the "GCC 16" build was still compiling GCC 13 sources |
removed; now -> ../gcc16/source |
| 5 | gcc13 / gcc13.cxx dependencies build the very compiler being replaced |
dropped |
| 6 | unknown type name 'bool' — GCC 16's sources are C23, where bool is a keyword, but the cookbook pins -std=gnu17 tree-wide for the C17-era recipes |
exempt this recipe from the pin |
| 7 | cannot guess version — same_as used to supply it; a path source gives the cookbook nothing to infer from |
explicit [package].version |
| 8 | 'fenv_t' has not been declared in '::' — dropping gcc13 also removed what transitively staged relibc's headers, leaving the sysroot with no libc headers at all |
explicit relibc dependency |
| 9 | _getopt_internal undeclared — libiberty needs GCC's own include/getopt.h, which declares that GNU-internal symbol; relibc's getopt.h was shadowing it |
GCC's include/ ahead of the sysroot |
| 10 | FNM_FILE_NAME / FNM_LEADING_DIR undeclared — GNU extensions genuinely absent from relibc |
implemented in the relibc fork (see below) |
Correction worth preserving
Finding #8 was initially misdiagnosed as "relibc's fenv.h is a 3-line
stub". It is not. relibc's fenv.h correctly delegates to openlibm_fenv.h,
which dispatches on __x86_64__ to openlibm_fenv_amd64.h where fenv_t
(line 48) and fexcept_t (line 50) are both defined — and relibc stages all of
those headers. The header was simply never reaching this recipe's sysroot. A
commit message asserting a relibc fenv gap was wrong and is corrected in the
commit that follows it.
The lesson generalises to most of this list: an "undeclared identifier" against relibc is more often a header-path problem than a missing implementation. Check whether the header reaches the compiler before concluding relibc is incomplete.
Real relibc gap that was fixed
FNM_FILE_NAME and FNM_LEADING_DIR are now implemented in
local/sources/relibc/src/header/fnmatch/mod.rs (pushed on
submodule/relibc). FNM_FILE_NAME is the GNU synonym for FNM_PATHNAME, so
an alias. FNM_LEADING_DIR is real behaviour — the pattern may match a leading
directory, so foo matches foo/bar — implemented by trying the exact match
then each prefix ending before a /. Declaring the flag without honouring it
would have been a stub. Its value (16) is the next free bit in relibc's own
numbering, not glibc's.
Where it stopped
/usr/include/c++/16/x86_64-pc-linux-gnu/bits/os_defines.h:44:
error: missing binary operator before token '('
The host's libstdc++ headers are being pulled into a target compile —
__GLIBC_PREREQ evaluated where there is no glibc. A host/target header leak,
and the natural next thing to investigate.
rust-native — four findings, one open
| # | Defect | Resolution |
|---|---|---|
| 1 | nix 0.30.1 incompatible with libc 0.2.178: declares SaFlags_t = c_ulong while libc has sa_flags/SA_* as c_int (E0308 both directions) |
nix 0.31 fixed it; ctrlc 3.5 requires nix "0.31" |
| 2 | in-tree miri pinned nix = "0.30.1" and held the broken version in the graph |
bumped; carried as local/patches/rust/01-miri-nix-0.31.patch |
| 3 | CLD_EXITED / P_ALL etc. not in crate libc — its Redox bindings never exposed the waitid surface relibc implements, still absent in 0.2.189 |
vendored fork, see VENDORED-LIBC-FORK.md |
| 4 | llvm/Config/llvm-config.h: No such file — llvm-native.dev (which stages the headers) missing from dependencies |
added |
Open: five error: unreachable 'pub' item diagnostics, crate not yet
identified. Not investigated.
Re-enabling
The recipes are fixed and committed, not reverted. To resume:
- In
config/redbear-full.toml, changegcc-native = "ignore"andrust-native = "ignore"back to= {}. ./local/scripts/build-redbear.sh --upstream redbear-full.- Expect to resume at the host/libstdc++ header leak above.
Diagnose failures in isolation — COOKBOOK_COOK_JOBS=1 ./target/release/repo cook <recipe>. The aggregate build multiplexes output from parallel cooks, and
several wrong turns in this workstream came from attributing one recipe's error
to another in the interleaved log.
Upstream-reportable
Two findings belong upstream rather than in Red Bear indefinitely:
- The
libccrate's Redox module lacks thewaitidsurface (idtype_t,P_*,CLD_*,waitid) that relibc implements. Retirement procedure inVENDORED-LIBC-FORK.md. - relibc's missing GNU
fnmatchextensions — now fixed in the fork, and worth offering upstream.