From c2fc7dd973578bb003725e4a3bdff122fd66df58 Mon Sep 17 00:00:00 2001 From: vasilito Date: Mon, 3 Aug 2026 19:44:49 +0300 Subject: [PATCH] docs: record the deferred native-toolchain workstream The config comment referencing this file was dangling. Captures the twelve gcc-native and four rust-native findings so the work is not lost: the GCC 13 -> 16 move and why (char8_t, libcody's C++11-only probe, the cpuid macros GCC 15/16 removed, then an ICE), the stale same_as symlink, the gnu17 exemption, the missing relibc dependency, the getopt.h shadowing, and the fnmatch extensions implemented in the fork. Records two things explicitly because they are easy to get wrong again: - The old 'Redox C++/pthread header gaps' justification was false. llvm-native cooks clean in isolation; it only failed in parallel builds because of a cookbook race on shared staging paths. A build-system bug had been misdiagnosed as a porting gap and used to exclude a required package. - My own 'relibc fenv.h is a stub' diagnosis was also false. relibc delegates to openlibm_fenv.h which defines both types; the header just was not reaching the sysroot. Generalised into a rule: an undeclared identifier against relibc is more often a header-path problem than a missing implementation. Also notes the exact stopping point (host libstdc++ headers leaking into a target compile), the re-enable procedure, and the advice to diagnose with COOKBOOK_COOK_JOBS=1 since several wrong turns came from attributing one recipe's error to another in the interleaved parallel log. --- docs/README.md | 1 + local/docs/NATIVE-TOOLCHAIN-WORKSTREAM.md | 162 ++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 local/docs/NATIVE-TOOLCHAIN-WORKSTREAM.md diff --git a/docs/README.md b/docs/README.md index fa6dd67a9a..eb37cdb6a5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -90,6 +90,7 @@ Do not flatten those into one “supported” claim in public summaries. - `../local/docs/SCRIPT-BEHAVIOR-MATRIX.md` — what the main sync/fetch/apply/build scripts do and do not guarantee - `../local/docs/FORK-BUMP-PATCHING-POLICY.md` — delicate patching during a version or toolchain bump (a bump is a rebase, never a replacement) +- `../local/docs/NATIVE-TOOLCHAIN-WORKSTREAM.md` — gcc-native/rust-native: deferred workstream, findings and re-enable procedure ## Current State Summary (as of 2026-07-18) diff --git a/local/docs/NATIVE-TOOLCHAIN-WORKSTREAM.md b/local/docs/NATIVE-TOOLCHAIN-WORKSTREAM.md new file mode 100644 index 0000000000..729dea9d81 --- /dev/null +++ b/local/docs/NATIVE-TOOLCHAIN-WORKSTREAM.md @@ -0,0 +1,162 @@ +# 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` — that recipe still builds the +GCC 13 cross toolchain and they are correct there. + +### 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: + +1. In `config/redbear-full.toml`, change `gcc-native = "ignore"` and + `rust-native = "ignore"` back to `= {}`. +2. `./local/scripts/build-redbear.sh --upstream redbear-full`. +3. Expect to resume at the host/libstdc++ header leak above. + +Diagnose failures **in isolation** — `COOKBOOK_COOK_JOBS=1 ./target/release/repo +cook `. 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 `libc` crate's Redox module lacks the `waitid` surface (`idtype_t`, + `P_*`, `CLD_*`, `waitid`) that relibc implements. Retirement procedure in + `VENDORED-LIBC-FORK.md`. +- relibc's missing GNU `fnmatch` extensions — now fixed in the fork, and worth + offering upstream.