gcc: extract the Redox target port as a version-portable artifact

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.
This commit is contained in:
2026-08-03 11:27:17 +03:00
parent 675c5e82fc
commit c88ddabcdd
8 changed files with 386 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
# Redox GCC target port — version-portable extraction
## Why this exists
Red Bear needs a newer GCC than Redox ships. Upstream
`gitlab.redox-os.org/redox-os/gcc` has only three branches — `redox`,
`redox-8.2.0`, `redox-13.2.0` — so there is **no GCC 14+ with Redox support**
to consume. The cross toolchain in `mk/prefix.mk` is pinned to `13.2.0` and
fetched prebuilt from `static.redox-os.org/toolchain/`.
KDE forces the issue: **KWin (16 files) and plasma-workspace (1 file)** use
C++23 `std::ranges::to`, and both declare `CMAKE_CXX_STANDARD 23`. GCC 13.2.0's
libstdc++ has no `ranges::to` (verified: no `__cpp_lib_ranges_to_container`,
`gcc/BASE-VER` = 13.2.0). Backporting call sites was rejected as the more
expensive path — it recurs on every KDE release and diverges from upstream KDE,
against the project's "adapt to upstream, never the reverse" rule.
## What the port actually is
Measured against `recipes/dev/gcc13/source`, the entire Redox port is **13
files**. It is a textbook GCC *target* port, not a compiler fork:
### Redox-owned files (captured verbatim under `files/`)
| File | Role |
|---|---|
| `gcc/config/redox.h` | target definition (36 lines) |
| `gcc/config/redox.opt` | target options (27 lines) |
| `gcc/config/i386/xm-redox.h` | x86_64 host-machine header |
| `gcc/config/aarch64/xm-redox.h` | aarch64 host-machine header |
| `gcc/config/riscv/xm-redox.h` | riscv host-machine header |
Only the i386 one matters for Red Bear (amd64-only per `local/AGENTS.md`), but
all are kept so the port stays faithful to upstream Redox.
### Registration points in existing GCC files
Recorded in `registration-points.txt` (line numbers) and
`registration-hunks.txt` (with surrounding context):
`config.sub`, `gcc/config.gcc`, `gcc/config.host`, `gcc/config.build`,
`libgcc/config.host`, `libstdc++-v3/crossconfig.m4`,
`libstdc++-v3/config/os/generic/os_defines.h`, `fixincludes/mkfixinc.sh`
These are `*-*-redox*` case arms — the kind of plumbing that changes slowly
between GCC releases, so they are expected to re-apply with light editing.
Note `gcc/configure` and `libstdc++-v3/configure` also match "redox", but they
are GENERATED from `configure.ac` / `crossconfig.m4`. Do not hand-edit them;
regenerate with autoconf.
## Applying to a new GCC
1. Check out the upstream GCC release tag (e.g. `releases/gcc-16.1.0`).
2. Copy `files/` over the tree.
3. Re-apply each arm in `registration-hunks.txt`; the anchors are stable
(`*-*-redox*`, `x86_64-*-redox*`).
4. Regenerate `configure` from `crossconfig.m4` with autoconf.
5. Build the cross compiler and stage it into `prefix/`.
## Known risks (measured, not speculative)
- **libstdc++ ABI change** — every C++ package (Qt6, 40+ KF6, Plasma, Mesa C++)
must be rebuilt. This is a full-tree rebuild, not a toolchain swap.
- **Toolchain ownership** — `mk/prefix.mk` currently *downloads* the toolchain
from `static.redox-os.org`. Building our own GCC means hosting/producing it
ourselves, permanently. This is the main long-term cost, larger than the port.
- **relibc header interactions** — the repo already documents fights between
relibc's cbindgen headers and GCC (`__need_wint_t`, `__GLIBC_USE`,
`stddef.h` circular includes; see `AGENTS.md` § relibc Header Circular
Includes). A stricter/newer GCC is likely to reopen that class.
- `mk/prefix.mk` hardcodes the string `13.2.0` in at least one path
(`.../lib/gcc/$(GNU_TARGET)/13.2.0/include/limits.h`) and must be
parameterized.
## Why Redox stays on 13.2.0
Inference, not a maintainer statement: Redox's own toolchain is
Clang/LLVM-21-centric and GCC is the secondary C/C++ path, so upgrade pressure
is low. They have jumped versions before (8.2.0 → 13.2.0), which argues the gap
is demand-driven rather than a technical blocker.
@@ -0,0 +1,2 @@
#define HOST_BIT_BUCKET "null:"
#define PATH_SEPARATOR ':'
@@ -0,0 +1,2 @@
#define HOST_BIT_BUCKET "null:"
#define PATH_SEPARATOR ':'
@@ -0,0 +1,36 @@
#undef TARGET_REDOX
#define TARGET_REDOX 1
#undef CPP_SPEC
#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}"
#undef LIB_SPEC
#define LIB_SPEC "%{pthread:-lpthread} -lc %{!static:-lgcc_s}"
#undef LINK_SPEC
#define LINK_SPEC "%{shared:-shared} %{static:-static} %{!shared: %{!static: %{rdynamic:-export-dynamic}}}"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{!shared:crt0.o%s} crti.o%s %{shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
do { \
builtin_define ("__redox__"); \
builtin_define ("__unix__"); \
builtin_assert ("system=redox"); \
builtin_assert ("system=unix"); \
builtin_assert ("system=posix"); \
} while(0);
#undef TARGET_DEFAULT_SMALL_DATA_SIZE
#define TARGET_DEFAULT_SMALL_DATA_SIZE 0
/* Use int, instead of long int, for int32_t and uint32_t. */
#undef STDINT_LONG32
#define STDINT_LONG32 0
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
@@ -0,0 +1,27 @@
; Redox-specific options.
; Copyright (C) 2013-2020 Free Software Foundation, Inc.
;
; This file is part of GCC.
;
; GCC is free software; you can redistribute it and/or modify it under
; the terms of the GNU General Public License as published by the Free
; Software Foundation; either version 3, or (at your option) any later
; version.
;
; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
; WARRANTY; without even the implied warranty of MERCHANTABILITY or
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
; for more details.
;
; You should have received a copy of the GNU General Public License
; along with GCC; see the file COPYING3. If not see
; <http://www.gnu.org/licenses/>.
pthread
Driver
rdynamic
Driver
; Retain blank line above
@@ -0,0 +1,2 @@
#define HOST_BIT_BUCKET "null:"
#define PATH_SEPARATOR ':'
@@ -0,0 +1,197 @@
==================== gcc/config.gcc
927- ;;
928- esac
929- ;;
930:*-*-redox*)
931- gas=yes
932- gnu_ld=yes
933- default_use_cxa_atexit=yes
934- gcc_cv_initfini_array=yes
935- tmake_file="${tmake_file} t-slibgcc"
936: extra_options="${extra_options} redox.opt"
937- case ${enable_threads} in
938- yes)
939- thread_file='posix'
940- ;;
941- esac
942- case ${target} in
943: i[34567]86-*-redox* | x86_64-*-redox*)
944: xm_file=i386/xm-redox.h
945- ;;
946: aarch64-*-redox*)
947: xm_file=aarch64/xm-redox.h
948- ;;
949: riscv64*-*-redox*)
950: xm_file=riscv/xm-redox.h
951- ;;
952- esac
953- ;;
954-*-*-netbsd*)
955- tm_p_file="${tm_p_file} netbsd-protos.h"
956- tmake_file="t-netbsd t-slibgcc"
957- extra_objs="${extra_objs} netbsd.o"
958- d_target_objs="${d_target_objs} netbsd-d.o"
--
2036- done
2037- TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
2038- ;;
2039:aarch64-*-redox*)
2040: tm_file="${tm_file} elfos.h aarch64/aarch64-elf.h aarch64/aarch64-elf-raw.h redox.h newlib-stdint.h"
2041- tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
2042- ;;
2043:i[34567]86-*-redox*)
2044: tm_file="${tm_file} i386/unix.h i386/att.h elfos.h i386/i386elf.h redox.h newlib-stdint.h"
2045- ;;
2046:riscv64*-*-redox*)
2047: tm_file="${tm_file} elfos.h riscv/elf.h redox.h newlib-stdint.h"
2048- tmake_file="${tmake_file} ${cpu_type}/t-riscv"
2049- ;;
2050:x86_64-*-redox*)
2051: tm_file="${tm_file} i386/unix.h i386/att.h elfos.h i386/i386elf.h i386/x86-64.h redox.h newlib-stdint.h"
2052- ;;
2053-i[34567]86-pc-msdosdjgpp*)
2054- xm_file=i386/xm-djgpp.h
2055- tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/djgpp.h i386/djgpp-stdint.h"
2056- native_system_header_dir=/dev/env/DJDIR/include
2057- extra_options="${extra_options} i386/djgpp.opt"
2058- gnu_ld=yes
2059- gas=yes
==================== gcc/config.host
295- host_exeext=.exe
296- host_can_use_collect2=no
297- ;;
298: i[34567]86-*-redox* | x86_64-*-redox*)
299: host_xm_file=i386/xm-redox.h
300- ;;
301: aarch64-*-redox*)
302: host_xm_file=aarch64/xm-redox.h
303- ;;
304: riscv64*-*-redox*)
305: host_xm_file=riscv/xm-redox.h
306- ;;
307-esac
==================== gcc/config.build
80- build_exeext=.exe
81- build_install_headers_dir=install-headers-cp
82- ;;
83: i[34567]86-*-redox* | x86_64-*-redox* )
84: build_xm_file=i386/xm-redox.h
85- ;;
86: aarch64-*-redox*)
87: build_xm_file=aarch64/xm-redox.h
88- ;;
89: riscv64*-*-redox*)
90: build_xm_file=riscv/xm-redox.h
91- ;;
92-esac
93-
==================== libgcc/config.host
306- ;;
307- esac
308- ;;
309:*-*-redox*)
310- extra_parts="$extra_parts crtbegin.o crtbeginS.o crtend.o crtendS.o"
311- tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic"
312- tmake_file="$tmake_file t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver"
313- ;;
314-*-*-rtems*)
315- tmake_file="$tmake_file t-rtems"
316- extra_parts="crtbegin.o crtend.o"
317- ;;
--
780- tm_file="${tm_file} i386/elf-lib.h"
781- md_unwind_header=i386/gnu-unwind.h
782- ;;
783:i[34567]86-*-redox*)
784- tmake_file="$tmake_file i386/t-crtstuff"
785- ;;
786:x86_64-*-redox*)
787- tmake_file="$tmake_file i386/t-crtstuff"
788- ;;
789:aarch64-*-redox*)
790- extra_parts="$extra_parts crtfastmath.o"
791- tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
792- tmake_file="${tmake_file} ${cpu_type}/t-lse t-slibgcc-libgcc"
793- tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm"
794- md_unwind_header=aarch64/aarch64-unwind.h
795- ;;
796:riscv64*-*-redox*)
797- tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address} t-slibgcc-libgcc"
798- ;;
799-i[34567]86-pc-msdosdjgpp*)
800- ;;
801-i[34567]86-*-lynxos*)
802- ;;
803-i[34567]86-*-nto-qnx*)
804- tmake_file="$tmake_file i386/t-nto t-libgcc-pic"
==================== libstdc++-v3/crossconfig.m4
141- AC_SUBST(SECTION_FLAGS)
142- ;;
143-
144: aarch64-*-redox* | riscv64*-*-redox*)
145- SECTION_FLAGS='-ffunction-sections -fdata-sections'
146- AC_SUBST(SECTION_FLAGS)
147- AC_DEFINE(HAVE_ALIGNED_ALLOC)
148- ;;
149-
150- *-hpux*)
151- SECTION_FLAGS='-ffunction-sections -fdata-sections'
152- AC_SUBST(SECTION_FLAGS)
--
196- AC_CHECK_FUNCS(secure_getenv)
197- AM_ICONV
198- ;;
199: *-redox*)
200- GLIBCXX_CHECK_COMPILER_FEATURES
201- GLIBCXX_CHECK_LINKER_FEATURES
202- GLIBCXX_CHECK_MATH_SUPPORT
203- GLIBCXX_CHECK_STDLIB_SUPPORT
204- AC_CHECK_FUNCS(aligned_alloc posix_memalign memalign _aligned_malloc)
205- ;;
206- *-mingw32*)
207- GLIBCXX_CHECK_LINKER_FEATURES
==================== libstdc++-v3/config/os/generic/os_defines.h
38-// workaround in gthr-posix.h and at link-time for static linking.
39-#define _GLIBCXX_GTHREAD_USE_WEAK 0
40-
41:// Causes issues on Redox
42-#define _GLIBCXX_USE_WEAK_REF 0
43-
44-#endif
==================== config.sub
1746- | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \
1747- | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
1748- | skyos* | haiku* | rdos* | toppers* | drops* | es* \
1749: | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
1750- | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
1751- | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
1752- | fiwix* )
1753- ;;
1754- # This one is extra strict with allowed versions
1755- sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
1756- # Don't forget version if it is 3.2v4 or newer.
1757- ;;
==================== fixincludes/mkfixinc.sh
12-# Check for special fix rules for particular targets
13-case $machine in
14- i?86-*-cygwin* | \
15: aarch64-*-redox* | \
16: i?86-*-redox* | \
17: riscv64*-*-redox* | \
18: x86_64-*-redox* | \
19- i?86-*-mingw32* | \
20- x86_64-*-mingw32* | \
21- powerpc-*-eabisim* | \
22- powerpc-*-eabi* | \
23- powerpc-*-rtems* | \
24- powerpcle-*-eabisim* | \
25- powerpcle-*-eabi* | \
26- *-*-vxworks7* | \
@@ -0,0 +1,39 @@
### config.sub
1749: | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
### gcc/config.gcc
930:*-*-redox*)
936: extra_options="${extra_options} redox.opt"
943: i[34567]86-*-redox* | x86_64-*-redox*)
944: xm_file=i386/xm-redox.h
946: aarch64-*-redox*)
947: xm_file=aarch64/xm-redox.h
### gcc/config.host
298: i[34567]86-*-redox* | x86_64-*-redox*)
299: host_xm_file=i386/xm-redox.h
301: aarch64-*-redox*)
302: host_xm_file=aarch64/xm-redox.h
304: riscv64*-*-redox*)
305: host_xm_file=riscv/xm-redox.h
### gcc/config.build
83: i[34567]86-*-redox* | x86_64-*-redox* )
84: build_xm_file=i386/xm-redox.h
86: aarch64-*-redox*)
87: build_xm_file=aarch64/xm-redox.h
89: riscv64*-*-redox*)
90: build_xm_file=riscv/xm-redox.h
### libgcc/config.host
309:*-*-redox*)
783:i[34567]86-*-redox*)
786:x86_64-*-redox*)
789:aarch64-*-redox*)
796:riscv64*-*-redox*)
### libstdc++-v3/crossconfig.m4
144: aarch64-*-redox* | riscv64*-*-redox*)
199: *-redox*)
### libstdc++-v3/config/os/generic/os_defines.h
41:// Causes issues on Redox
### fixincludes/mkfixinc.sh
15: aarch64-*-redox* | \
16: i?86-*-redox* | \
17: riscv64*-*-redox* | \
18: x86_64-*-redox* | \