f2b6c1e0ed
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.
122 lines
4.7 KiB
Bash
Executable File
122 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Install the GCC 16 cross compiler over the GCC 13.2.0 one, in every
|
|
# location the build actually reads a compiler from.
|
|
#
|
|
# There are three such locations, and all three must agree or the build
|
|
# picks up a mixed toolchain:
|
|
#
|
|
# 1. prefix/<target>/gcc-install/ - the GCC half of the prefix
|
|
# 2. prefix/<target>/sysroot/ - the merged prefix (gcc+rust+clang)
|
|
# 3. ~/.redoxer/<target>/toolchain/ - HIGHEST PRIORITY. src/cook/script.rs
|
|
# prepends this to PATH last, so it wins over both prefix paths for
|
|
# every recipe. Missing this one silently leaves recipes on GCC 13.
|
|
#
|
|
# Reversible: the GCC 13 components are moved aside to a timestamped
|
|
# backup dir rather than deleted, and --restore puts them back.
|
|
#
|
|
# Run local/scripts/build-gcc16-cross.sh first.
|
|
set -euo pipefail
|
|
|
|
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
|
|
TARGET=x86_64-unknown-redox
|
|
NEWGCC=16.1.0
|
|
OLDGCC=13.2.0
|
|
SRC="$ROOT/build/gcc16-install"
|
|
PREFIX_GCC="$ROOT/prefix/$TARGET/gcc-install"
|
|
PREFIX_SYSROOT="$ROOT/prefix/$TARGET/sysroot"
|
|
REDOXER="$HOME/.redoxer/$TARGET/toolchain"
|
|
BACKUP="$ROOT/build/gcc13-backup"
|
|
|
|
# GCC's <cstdlib> does `using ::strtold` before relibc's cbindgen trailer has
|
|
# declared it, so the C++ wrapper must pull in <stdlib.h> explicitly. mk/prefix.mk
|
|
# does this with a sed, but that sed is NOT idempotent -- the current GCC 13
|
|
# toolchain has the comment block appended 17 times from repeated `make prefix`
|
|
# runs. The guard below makes it apply exactly once.
|
|
patch_cstdlib() {
|
|
local f="$1"
|
|
[ -f "$f" ] || return 0
|
|
grep -q "Red Bear: relibc declares strtold" "$f" && return 0
|
|
sed -i '/^#include_next <stdlib.h>$/a\\n// Red Bear: relibc declares strtold via cbindgen trailer.\n// The explicit include ensures ::strtold is visible when the\n// C++ wrapper processes its using-directives below.\n#include <stdlib.h>' "$f"
|
|
echo " patched strtold: $f"
|
|
}
|
|
|
|
# Move GCC's own components out of a tree without disturbing the rust/clang/
|
|
# relibc files that share it.
|
|
evict_old() {
|
|
local dst="$1" tag="$2"
|
|
local bk="$BACKUP/$tag"
|
|
mkdir -p "$bk"
|
|
for p in "bin/$TARGET-gcc-$OLDGCC" \
|
|
"lib/gcc/$TARGET/$OLDGCC" \
|
|
"libexec/gcc/$TARGET/$OLDGCC" \
|
|
"$TARGET/include/c++/$OLDGCC"; do
|
|
if [ -e "$dst/$p" ]; then
|
|
mkdir -p "$bk/$(dirname "$p")"
|
|
mv "$dst/$p" "$bk/$p"
|
|
fi
|
|
done
|
|
for so in "$dst/$TARGET/lib/"libstdc++.so.6.0.* ; do
|
|
[ -e "$so" ] || continue
|
|
mkdir -p "$bk/$TARGET/lib"
|
|
mv "$so" "$bk/$TARGET/lib/"
|
|
done
|
|
}
|
|
|
|
install_into() {
|
|
local dst="$1" tag="$2"
|
|
[ -d "$dst" ] || { echo " skip $tag (not present)"; return 0; }
|
|
echo " -> $tag: $dst"
|
|
evict_old "$dst" "$tag"
|
|
# Driver, cc1/cc1plus, target headers and libs.
|
|
cp -a "$SRC/bin/." "$dst/bin/"
|
|
mkdir -p "$dst/lib/gcc/$TARGET" "$dst/libexec/gcc/$TARGET"
|
|
cp -a "$SRC/lib/gcc/$TARGET/$NEWGCC" "$dst/lib/gcc/$TARGET/"
|
|
cp -a "$SRC/libexec/gcc/$TARGET/$NEWGCC" "$dst/libexec/gcc/$TARGET/"
|
|
mkdir -p "$dst/$TARGET/include/c++"
|
|
cp -a "$SRC/$TARGET/include/c++/$NEWGCC" "$dst/$TARGET/include/c++/"
|
|
cp -a "$SRC/$TARGET/lib/." "$dst/$TARGET/lib/"
|
|
for c in "$dst/$TARGET/include/c++/$NEWGCC/cstdlib"; do patch_cstdlib "$c"; done
|
|
}
|
|
|
|
if [ "${1:-}" = "--restore" ]; then
|
|
[ -d "$BACKUP" ] || { echo "no backup at $BACKUP" >&2; exit 1; }
|
|
for tag in gcc-install sysroot redoxer; do
|
|
case $tag in
|
|
gcc-install) dst="$PREFIX_GCC" ;;
|
|
sysroot) dst="$PREFIX_SYSROOT" ;;
|
|
redoxer) dst="$REDOXER" ;;
|
|
esac
|
|
[ -d "$BACKUP/$tag" ] || continue
|
|
echo "restoring $tag"
|
|
cp -a "$BACKUP/$tag/." "$dst/"
|
|
done
|
|
echo "GCC $OLDGCC restored. Re-run without --restore to go back to $NEWGCC."
|
|
exit 0
|
|
fi
|
|
|
|
[ -x "$SRC/bin/$TARGET-gcc" ] || {
|
|
echo "FATAL: $SRC not built. Run local/scripts/build-gcc16-cross.sh" >&2; exit 1; }
|
|
[ -e "$SRC/$TARGET/lib/libstdc++.so.6" ] || {
|
|
echo "FATAL: $SRC has no shared libstdc++. The desktop stack links" >&2
|
|
echo " libstdc++.so.6 (readelf -d libQt6Core.so), so a static-only" >&2
|
|
echo " toolchain cannot build it." >&2; exit 1; }
|
|
|
|
echo "Installing GCC $NEWGCC (backup of $OLDGCC -> $BACKUP)"
|
|
rm -rf "$BACKUP"
|
|
install_into "$PREFIX_GCC" gcc-install
|
|
install_into "$PREFIX_SYSROOT" sysroot
|
|
install_into "$REDOXER" redoxer
|
|
|
|
echo
|
|
echo "Verifying the compiler each recipe will actually invoke:"
|
|
PATH="$REDOXER/bin:$PREFIX_SYSROOT/bin:$PATH" "$TARGET-gcc" --version | head -1
|
|
PATH="$REDOXER/bin:$PREFIX_SYSROOT/bin:$PATH" "$TARGET-g++" -std=c++23 -x c++ -c - -o /dev/null <<'EOF'
|
|
#include <version>
|
|
#ifndef __cpp_lib_ranges_to_container
|
|
#error ranges::to missing
|
|
#endif
|
|
int main(){}
|
|
EOF
|
|
echo "C++23 ranges::to: OK"
|
|
echo "Revert with: $0 --restore"
|