docs(native-toolchain): record findings 5-7 and correct the leak direction
rust-native now builds. Records the three defects found getting there (host/target header leak, the -fno-hardened cross-flag leak, relibc's duplicate _POSIX_THREADS) and closes the previously-open "unreachable 'pub' item" item, which deny-warnings = false already resolved. Corrects the gcc-native diagnosis. It read "the host's libstdc++ headers are being pulled into a target compile"; the direction is the reverse -- relibc's TARGET headers reach a HOST compile through the redoxer toolchain's mixed include/ directory, so __GLIBC_PREREQ is undefined where the host headers expect it. That matters for how gcc-native gets unblocked: the host: package pattern used for rust-native should apply, rather than reworking GCC's cross-build header model. Status flipped DEFERRED -> ACTIVE per the 2026-08-05 operator decision.
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
# 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."*
|
||||
**Status:** ACTIVE. Deferred 2026-08-03 (*"Treat gcc-native/rust-native as a
|
||||
separate workstream, explicitly deferred by me, for now."*), then RE-ENABLED by
|
||||
explicit operator decision, 2026-08-05: *"Build and add gcc-native and
|
||||
rust-native to project."* Both are `= {}` in `config/redbear-full.toml` again.
|
||||
**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
|
||||
@@ -124,9 +125,26 @@ numbering, not glibc's.
|
||||
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.
|
||||
**Root cause identified 2026-08-05 while unblocking `rust-native` — it is the
|
||||
same defect, and it is now understood.** The initial reading above ("host
|
||||
libstdc++ headers pulled into a target compile") had the direction backwards.
|
||||
What actually happens is the reverse: `${HOME}/.redoxer/${TARGET}/toolchain/include`
|
||||
is a MIXED directory holding relibc's **target** headers (`stdlib.h`,
|
||||
`features.h`, `fenv.h`, …) beside the `llvm/` and `clang/` ones. When that
|
||||
directory reaches a **host** compile via `-I`, relibc's `features.h` shadows
|
||||
glibc's, `__GLIBC_PREREQ` is never defined, and every host libstdc++/glibc
|
||||
header testing it fails. Reproducible in three lines, no rustc or GCC build
|
||||
involved:
|
||||
|
||||
```
|
||||
printf '#include <cstdlib>\nint main(){}' > t.cpp
|
||||
c++ -std=c++17 -I${HOME}/.redoxer/x86_64-unknown-redox/toolchain/include -c t.cpp
|
||||
```
|
||||
|
||||
So this is a target→host leak, not a host→target one. See the `rust-native`
|
||||
finding #5 below for the fix pattern (`host:` packages stage into
|
||||
`COOKBOOK_TOOLCHAIN`, which is a separate tree from the target sysroot); the
|
||||
same approach should apply here.
|
||||
|
||||
## `rust-native` — four findings, one open
|
||||
|
||||
@@ -136,18 +154,30 @@ and the natural next thing to investigate.
|
||||
| 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 |
|
||||
| 5 | ~200 errors in the HOST's own glibc/libstdc++ headers building `rustc_llvm` for the host triple. `rustc_llvm`'s build script feeds `llvm-config --includedir` straight to the host `c++`, and the redoxer toolchain's `include/` is the mixed dir described under gcc-native above | `host:llvm-native` (+ `.dev`/`.runtime`). Host deps stage into `COOKBOOK_TOOLCHAIN`, a tree SEPARATE from the target sysroot, so the host LLVM and the Redox `llvm21` coexist instead of overwriting each other — which is the collision the recipe's `llvm21` comment records |
|
||||
| 6 | `c++: error: unknown argument: '-fno-hardened'`. `DYNAMIC_INIT` exports `CXXFLAGS=-fno-hardened` for the GCC 16 **cross** compiler; the recipe's `unset` list dropped `CC`/`CXX`/`LDFLAGS` but not `CFLAGS`/`CXXFLAGS`/`CPPFLAGS`, so it leaked into the host stage1 build, where `c++` now resolves through `COOKBOOK_TOOLCHAIN/bin` to llvm-native's clang++ | added `CFLAGS CXXFLAGS CPPFLAGS` to the unset. Pre-existing leak; the cross `recipes/dev/rust` has the same list and never hit it only because nothing puts a clang on its PATH |
|
||||
| 7 | `'_POSIX_THREADS' redefined [-Werror]` building `rustc_llvm` for the **target**. relibc defined it twice: `unistd.h` `202405L` (correct — POSIX puts it there) and `pthread.h` `1`, emitted from a `pub const` in `src/header/pthread/mod.rs` that had zero users | deleted the dead constant in the relibc fork (`851a505f` on `submodule/relibc`), + prefix rebuild |
|
||||
|
||||
**Open:** five `error: unreachable 'pub' item` diagnostics, crate not yet
|
||||
identified. Not investigated.
|
||||
**Findings 5 and 6 were pre-existing latent defects**, not regressions: #5 is
|
||||
the same root cause as gcc-native's stopping point, and #6 only becomes
|
||||
reachable once a clang is on PATH. #7 broke any `-Werror` C++ TU including both
|
||||
headers, which is every C++ TU — libstdc++'s `<iterator>` chain reaches
|
||||
`pthread.h` via `gthr-default.h`.
|
||||
|
||||
**Closed:** the five `error: unreachable 'pub' item` diagnostics are resolved by
|
||||
`deny-warnings = false` in `config.toml` (documented in that file: the vendored
|
||||
libc fork arrives as a PATH dependency, so cargo's `--cap-lints allow` for
|
||||
registry deps does not apply to it).
|
||||
|
||||
## Re-enabling
|
||||
|
||||
The recipes are **fixed and committed, not reverted**. To resume:
|
||||
Both were re-enabled in `config/redbear-full.toml` on 2026-08-05; nothing needs
|
||||
un-ignoring. Build with
|
||||
`./local/scripts/build-redbear.sh --upstream redbear-full`.
|
||||
|
||||
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.
|
||||
`gcc-native` should now resume past its recorded stopping point using the
|
||||
finding-#5 pattern (a `host:` package, so the host compile never sees the mixed
|
||||
redoxer include dir) rather than by patching GCC's header model incrementally.
|
||||
|
||||
Diagnose failures **in isolation** — `COOKBOOK_COOK_JOBS=1 ./target/release/repo
|
||||
cook <recipe>`. The aggregate build multiplexes output from parallel cooks, and
|
||||
@@ -163,3 +193,6 @@ Two findings belong upstream rather than in Red Bear indefinitely:
|
||||
`VENDORED-LIBC-FORK.md`.
|
||||
- relibc's missing GNU `fnmatch` extensions — now fixed in the fork, and worth
|
||||
offering upstream.
|
||||
- relibc's duplicate `_POSIX_THREADS` (finding #7) — the `pthread.h` copy is
|
||||
both misplaced per POSIX and carries an invalid value. Fixed in the fork and
|
||||
worth offering upstream.
|
||||
|
||||
Reference in New Issue
Block a user