Files
RedBear-OS/mk/prefix.mk
T
vasilito a287fe20b9
redbear-ci / check (push) Has been cancelled
toolchain: remove the GCC 13 path; document the GCC 16 transition
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>
2026-08-05 10:11:06 +03:00

531 lines
24 KiB
Makefile

# Configuration file for the Rust/GCC cross-compilers, relibc and libtool
PREFIX=prefix/$(TARGET)
TOOLCHAIN_EXPORT_DIR?=$(ROOT)/build/toolchain-export/$(TARGET)
PREFIX_INSTALL=$(PREFIX)/sysroot/
PREFIX_PATH=$(ROOT)/$(PREFIX_INSTALL)/bin
BINUTILS_TARGET=recipes/dev/binutils-gdb/target/$(HOST_TARGET)/$(TARGET)
LIBTOOL_TARGET=recipes/dev/libtool/target/$(HOST_TARGET)
# Which GCC recipe the from-source toolchain path cooks. Red Bear's cross
# toolchain is GCC 16.1.0; there is no GCC 13 fallback in this fork. See
# local/docs/TOOLCHAIN-GCC16.md.
GCC_RECIPE?=gcc16
GCC_TARGET=recipes/dev/$(GCC_RECIPE)/target/$(HOST_TARGET)/$(TARGET)
LIBSTDCXX_TARGET=recipes/libs/libstdcxx-v3/target/$(TARGET)/$(HOST_TARGET)
RELIBC_FREESTANDING_TARGET=recipes/core/relibc/target/$(TARGET)/$(HOST_TARGET)
RELIBC_TARGET=recipes/core/relibc/target/$(TARGET)
LLVM_TARGET=recipes/dev/llvm21/target/$(HOST_TARGET)/$(TARGET)
RUST_TARGET=recipes/dev/rust/target/$(HOST_TARGET)/$(TARGET)
CLANG_TARGET=recipes/dev/clang21/target/$(HOST_TARGET)/$(TARGET)
LLD_TARGET=recipes/dev/lld21/target/$(HOST_TARGET)/$(TARGET)
# official RISC-V support introduced in newer version
UPSTREAM_RUSTC_VERSION=2025-11-15
export PREFIX_RUSTFLAGS=-L $(ROOT)/$(PREFIX_INSTALL)/$(TARGET)/lib
# Use the redoxer toolchain (Rust 1.98) for all recipe builds.
# The prefix sysroot provides the C cross-compiler (GCC/Clang/LLD) and
# relibc artifacts (libc.a, headers). The Rust compiler itself comes
# from the redoxer installation at ~/.redoxer/$(TARGET)/toolchain/,
# which is kept in sync with the prefix via rsync (see sysroot target).
# This avoids the dual-Rust-version problem where the prefix's bundled
# Rust (nightly-2025-11-15, ~1.92) and the redoxer Rust (1.98) have
# incompatible VaList APIs.
export REDOXER_TOOLCHAIN=$(HOME)/.redoxer/$(TARGET)/toolchain
PREFIX_CONFIG=CI=1 COOKBOOK_CLEAN_BUILD=true COOKBOOK_CLEAN_TARGET=false COOKBOOK_VERBOSE=true COOKBOOK_NONSTOP=false
prefix: $(PREFIX)/sysroot
export-toolchain: $(PREFIX)/sysroot FORCE
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@ TOOLCHAIN_EXPORT_DIR="$(TOOLCHAIN_EXPORT_DIR)"
else
"$(ROOT)/local/scripts/export-$(TARGET)-toolchain.sh" "$(TOOLCHAIN_EXPORT_DIR)"
endif
# Remove prefix builds and downloads
prefix_clean:
rm -rf $(PREFIX)
# Remove relibc in sysroot and all statically linked recipes
static_clean: | $(FSTOOLS_TAG)
$(MAKE) c.relibc
$(MAKE) c.base,base-initfs,extrautils,kernel,ion,pkgutils,redoxfs
$(MAKE) c.bash,luajit,gettext,openssl1,openssl3,pcre2,sdl1,zstd,zlib,bzip2,xz
$(MAKE) c.expat,freetype2,libffi,libiconv,libjpeg,liborbital,libpng,libxml2,ncurses,ncursesw
rm -rf $(REPO_TAG)
$(PREFIX)/relibc-install: $(PREFIX)/clang-install $(PREFIX)/rust-install $(PREFIX)/gcc-install | $(FSTOOLS_TAG) $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
@echo "\033[1;36;49mBuilding relibc-install\033[0m"
rm -rf "$@.partial" "$@"
mkdir "$@.partial"
cp -r "$(PREFIX)/gcc-install/". "$@.partial"
cp -r "$(PREFIX)/rust-install/". "$@.partial"
cp -r "$(PREFIX)/clang-install/". "$@.partial"
ifneq ($(HOSTED_REDOX),1)
rm -rf "$@.partial/$(GNU_TARGET)/include/"*
cp -r "$(PREFIX)/gcc-install/$(GNU_TARGET)/include/c++" "$@.partial/$(GNU_TARGET)/include/c++"
else
rm -rf "$@.partial/include/"*
cp -r "$(PREFIX)/gcc-install/include/c++" "$@.partial/include/c++"
endif
export PATH="$(ROOT)/$@.partial/bin:$$PATH" && \
export COOKBOOK_TOOLCHAIN="$(ROOT)/$@.partial" REDBEAR_REDOX_SYSROOT="$(ROOT)/$@.partial" && \
export CARGO="env -u CARGO cargo" $(PREFIX_CONFIG) && \
$(REPO_BIN) cook relibc
ifneq ($(HOSTED_REDOX),1)
cp -r "$(RELIBC_TARGET)/stage/usr/". "$@.partial/$(GNU_TARGET)"
mkdir -p "$@.partial/$(GNU_TARGET)/usr"
ln -s "../include" "$@.partial/$(GNU_TARGET)/usr/include"
ln -s "../lib" "$@.partial/$(GNU_TARGET)/usr/lib"
else
cp -r "$(RELIBC_TARGET)/stage/usr/". "$@.partial"
mkdir -p "$@.partial/usr"
ln -s "../include" "$@.partial/usr/include"
ln -s "../lib" "$@.partial/usr/lib"
endif
touch "$@.partial"
mv "$@.partial" "$@"
endif
$(PREFIX)/relibc-install.tar.gz: $(PREFIX)/relibc-install
tar \
--create \
--gzip \
--file "$@" \
--directory="$<" \
.
$(PREFIX)/sysroot: $(PREFIX)/relibc-install $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
rm -rf "$@"
cp -r "$(PREFIX)/relibc-install/" "$@"
# Patch relibc sysroot and redoxer toolchain GCC <cstdlib> for strtold.
# relibc declares strtold in stdlib.h (cbindgen trailer) but GCC's
# cstdlib does 'using ::strtold' before the trailer is processed.
# Add explicit #include <stdlib.h> after #include_next <stdlib.h>
# so ::strtold is visible when the C++ wrapper runs its using.
for _cstdlib in "$(COOKBOOK_ROOT)/prefix/${TARGET}/sysroot/${GNU_TARGET}/include/c++"/*/cstdlib; do \
[ -f "$$_cstdlib" ] || continue; \
grep -q 'Red Bear: relibc declares strtold' "$$_cstdlib" && continue; \
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>' "$$_cstdlib"; \
done
@REDOXER_TC=$(HOME)/.redoxer/$(TARGET)/toolchain/$(GNU_TARGET); \
if [ -d "$$REDOXER_TC/include/c++" ]; then \
for _cstdlib in "$$REDOXER_TC/include/c++"/*/cstdlib; do \
[ -f "$$_cstdlib" ] || continue; \
grep -q 'Red Bear: relibc declares strtold' "$$_cstdlib" && continue; \
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>' "$$_cstdlib"; \
done; \
fi
# Propagate fresh relibc artifacts (libc.a, crt*.o, headers) from the
# rebuilt sysroot back into gcc-install. The GCC driver's built-in
# library search path always looks inside gcc-install/ first; if that
# copy is stale (from the original GCC bootstrap) the linker silently
# picks up an outdated libc.a and we get spurious undefined-reference
# errors for symbols that exist only in the new relibc (e.g. __fseterr,
# __freadahead, eventfd helpers, …). This sync guarantees that every
# libc.a copy in the toolchain is identical to the one just compiled.
cp -rf "$@/$(GNU_TARGET)/lib/"* "$(PREFIX)/gcc-install/$(GNU_TARGET)/lib/"
cp -rf "$@/$(GNU_TARGET)/include/"* "$(PREFIX)/gcc-install/$(GNU_TARGET)/include/"
# Relibc declares strtold in stdlib.h, but GCC <cstdlib>'s include_next
# may not find it before processing 'using ::strtold'. Prepend an
# explicit #include <stdlib.h> to the C++ header so ::strtold is in
# scope by the time the using-directives execute. The edit must
# happen AFTER the #include_next <stdlib.h> line (which brings in
# most of the C declarations) but BEFORE the first using-directive.
for _cstdlib in "$(PREFIX)/gcc-install/$(GNU_TARGET)/include/c++"/*/cstdlib; do \
[ -f "$$_cstdlib" ] || continue; \
grep -q 'Red Bear: relibc declares strtold' "$$_cstdlib" && continue; \
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>' "$$_cstdlib"; \
done
# Propagate fresh relibc artifacts to the redoxer toolchain at
# ~/.redoxer/<target>/toolchain/. The redoxer ships its own sysroot
# snapshot from initial setup; without this sync the GCC driver inside
# redoxer finds the stale libc.a via its built-in search path, causing
# the same undefined-reference class as the gcc-install drift above.
# Use rsync --delete so stale headers (e.g. spawn.h from an older relibc
# that no longer generates them) are removed, not just overwritten.
@REDOXER_TC=$(HOME)/.redoxer/$(TARGET)/toolchain/$(GNU_TARGET); \
if [ -d "$$REDOXER_TC/lib" ]; then \
rsync -a --delete "$@/$(GNU_TARGET)/lib/" "$$REDOXER_TC/lib/"; \
rsync -a --delete "$@/$(GNU_TARGET)/include/" "$$REDOXER_TC/include/"; \
echo " [sysroot] synced relibc to redoxer toolchain (rsync --delete)"; \
fi
# adapt path for libtoolize
sed 's|/usr/share|$(ROOT)/$@/share|g' "$@/bin/libtoolize.orig" > "$@/bin/libtoolize"
chmod 0755 "$@/bin/libtoolize"
touch "$@"
endif
# PREFIX_BINARY ---------------------------------------------------
ifeq ($(PREFIX_BINARY),1)
# PREFIX_BINARY FOR LINUX -----------------------------------------
ifneq ($(HOSTED_REDOX),1)
$(PREFIX)/%.tar.gz: | $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
mkdir -p "$(@D)"
wget --tries=3 --timeout=30 --waitretry=5 -O $@.partial "https://static.redox-os.org/toolchain/$(HOST_TARGET)/$(TARGET)/$(@F)"
@test -s $@.partial || { echo "Error: download failed or produced empty file: $@"; rm -f $@.partial; exit 1; }
mv $@.partial $@
endif
$(PREFIX)/gcc-install $(PREFIX)/rust-install $(PREFIX)/clang-install: %: %.tar.gz | $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
rm -rf "$@.partial" "$@"
mkdir -p "$@.partial"
tar --extract --file "$<" --directory "$@.partial" --no-same-owner --strip-components=1
touch "$@.partial"
mv "$@.partial" "$@"
endif
# PREFIX_BINARY FOR REDOX -----------------------------------------
else
$(PREFIX)/id_ed25519.pub.toml: | $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
mkdir -p "$(@D)"
wget --tries=3 --timeout=30 --waitretry=5 -O $@.partial "https://static.redox-os.org/pkg/id_ed25519.pub.toml"
@test -s $@.partial || { echo "Error: download failed or produced empty file: $@"; rm -f $@.partial; exit 1; }
mv $@.partial $@
endif
$(PREFIX)/%.pkgar: $(PREFIX)/id_ed25519.pub.toml | $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
mkdir -p "$(@D)"
wget --tries=3 --timeout=30 --waitretry=5 -O $@.partial "https://static.redox-os.org/pkg/$(TARGET)/$(@F)"
@test -s $@.partial || { echo "Error: download failed or produced empty file: $@"; rm -f $@.partial; exit 1; }
mv $@.partial $@
endif
# Redox-hosted (HOSTED_REDOX=1) prefix. The package names follow GCC_RECIPE
# rather than being pinned to gcc13: this fork's toolchain is GCC 16 and must
# not silently seed a GCC 13 compiler. Note that static.redox-os.org publishes
# no gcc16 package, so this path fails at download until Red Bear hosts its
# own — deliberate, and a loud failure rather than a wrong compiler.
$(PREFIX)/gcc-install: $(PREFIX)/$(GCC_RECIPE).pkgar $(PREFIX)/$(GCC_RECIPE).cxx.pkgar $(PREFIX)/libgcc.pkgar $(PREFIX)/libstdcxx.pkgar $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
rm -rf "$@.partial" "$@"
mkdir -p "$@.partial"
pkgar extract --pkey $(PREFIX)/id_ed25519.pub.toml --archive "$(PREFIX)/$(GCC_RECIPE).pkgar" "$@.partial"
pkgar extract --pkey $(PREFIX)/id_ed25519.pub.toml --archive "$(PREFIX)/$(GCC_RECIPE).cxx.pkgar" "$@.partial"
pkgar extract --pkey $(PREFIX)/id_ed25519.pub.toml --archive "$(PREFIX)/libgcc.pkgar" "$@.partial"
pkgar extract --pkey $(PREFIX)/id_ed25519.pub.toml --archive "$(PREFIX)/libstdcxx.pkgar" "$@.partial"
mv "$@.partial/usr"/* "$@.partial"
rmdir "$@.partial/usr"
touch "$@.partial"
mv "$@.partial" "$@"
endif
$(PREFIX)/rust-install: $(PREFIX)/llvm21.pkgar $(PREFIX)/rust.pkgar $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
rm -rf "$@.partial" "$@"
mkdir -p "$@.partial"
pkgar extract --pkey $(PREFIX)/id_ed25519.pub.toml --archive "$(PREFIX)/llvm21.pkgar" "$@.partial"
pkgar extract --pkey $(PREFIX)/id_ed25519.pub.toml --archive "$(PREFIX)/rust.pkgar" "$@.partial"
mv "$@.partial/usr"/* "$@.partial"
rmdir "$@.partial/usr"
touch "$@.partial"
mv "$@.partial" "$@"
endif
$(PREFIX)/clang-install: $(PREFIX)/llvm21.runtime.pkgar $(PREFIX)/clang21.pkgar $(PREFIX)/lld21.pkgar $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
rm -rf "$@.partial" "$@"
mkdir -p "$@.partial"
pkgar extract --pkey $(PREFIX)/id_ed25519.pub.toml --archive "$(PREFIX)/llvm21.runtime.pkgar" "$@.partial"
pkgar extract --pkey $(PREFIX)/id_ed25519.pub.toml --archive "$(PREFIX)/clang21.pkgar" "$@.partial"
pkgar extract --pkey $(PREFIX)/id_ed25519.pub.toml --archive "$(PREFIX)/lld21.pkgar" "$@.partial"
mv "$@.partial/usr"/* "$@.partial"
rmdir "$@.partial/usr"
touch "$@.partial"
mv "$@.partial" "$@"
endif
endif
else
$(PREFIX)/%.tar.gz: $(PREFIX)/%
tar \
--create \
--gzip \
--file "$@" \
--directory="$<" \
.
# BUILD GCC ---------------------------------------------------
$(PREFIX)/libtool-install: | $(FSTOOLS_TAG) $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
@echo "\033[1;36;49mBuilding libtool-install\033[0m"
rm -rf "$@.partial" "$@"
mkdir -p "$@.partial"
export $(PREFIX_CONFIG) COOKBOOK_HOST_SYSROOT=/usr && \
$(REPO_BIN) cook host:libtool
cp -r "$(LIBTOOL_TARGET)/stage/usr/". "$@.partial"
mv "$@.partial/bin/libtoolize" "$@.partial/bin/libtoolize.orig"
# adapt path for libtoolize
sed 's|/usr/share|$(ROOT)/$@/share|g' "$@.partial/bin/libtoolize.orig" > "$@.partial/bin/libtoolize"
chmod 0755 "$@.partial/bin/libtoolize"
touch "$@.partial"
mv "$@.partial" "$@"
endif
$(PREFIX)/binutils-install: | $(PREFIX)/libtool-install $(FSTOOLS_TAG) $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
@echo "\033[1;36;49mBuilding binutils-install\033[0m"
rm -rf "$@.partial" "$@"
mkdir -p "$@.partial"
export $(PREFIX_CONFIG) PATH="$(ROOT)/$(PREFIX)/libtool-install/bin:$$PATH" \
COOKBOOK_HOST_SYSROOT=/usr COOKBOOK_CROSS_TARGET=$(TARGET) COOKBOOK_CROSS_GNU_TARGET=$(GNU_TARGET) && \
$(REPO_BIN) cook host:binutils-gdb
cp -r "$(BINUTILS_TARGET)/stage/usr/". "$@.partial"
touch "$@.partial"
mv "$@.partial" "$@"
endif
$(PREFIX)/gcc-freestanding-install: $(PREFIX)/binutils-install | $(PREFIX)/libtool-install $(FSTOOLS_TAG) $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
@echo "\033[1;36;49mBuilding gcc-freestanding-install\033[0m"
rm -rf "$@.partial" "$@" $(PREFIX)/relibc-freestanding-install $(PREFIX)/sysroot
mkdir -p "$@.partial" $(PREFIX)/relibc-freestanding-install/$(GNU_TARGET)/include
export $(PREFIX_CONFIG) PATH="$(ROOT)/$(PREFIX)/libtool-install/bin:$(ROOT)/$(PREFIX)/binutils-install/bin:$$PATH" \
COOKBOOK_LIBTOOL_DIR=$(ROOT)/$(PREFIX)/libtool-install COOKBOOK_CROSS_TARGET=$(TARGET) COOKBOOK_CROSS_GNU_TARGET=$(GNU_TARGET) \
COOKBOOK_HOST_SYSROOT=/usr COOKBOOK_CROSS_SYSROOT=$(ROOT)/$(PREFIX)/relibc-freestanding-install/$(GNU_TARGET) && \
$(REPO_BIN) cook host:$(GCC_RECIPE)
cp -r "$(GCC_TARGET)/stage/usr/". "$@.partial"
cp -r "$(GCC_TARGET)/stage.cxx/usr/". "$@.partial"
cp -r "$(PREFIX)/binutils-install/". "$@.partial"
rm -rf $(PREFIX)/relibc-freestanding-install
touch "$@.partial"
mv "$@.partial" "$@"
endif
$(PREFIX)/relibc-freestanding-install: $(PREFIX)/gcc-freestanding-install | $(FSTOOLS_TAG) $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
@echo "\033[1;36;49mBuilding relibc-freestanding-install\033[0m"
rm -rf "$@.partial" "$@"
mkdir -p "$@.partial"
export CARGO="env -u CARGO -u RUSTUP_TOOLCHAIN cargo" RUSTUP="env -u CARGO -u RUSTUP_TOOLCHAIN rustup" && \
export PATH="$(ROOT)/$(PREFIX)/gcc-freestanding-install/bin:$$PATH" && \
export CC_$(subst -,_,$(TARGET))="$(GNU_TARGET)-gcc -isystem $(ROOT)/$@.partial/$(GNU_TARGET)/include" LINKFLAGS="" && \
export $(PREFIX_CONFIG) COOKBOOK_HOST_SYSROOT=/usr COOKBOOK_CROSS_TARGET=$(HOST_TARGET) && \
$(REPO_BIN) cook relibc
cp -r "$(RELIBC_FREESTANDING_TARGET)/stage/usr/". "$@.partial/$(GNU_TARGET)"
touch "$@.partial"
mv "$@.partial" "$@"
endif
$(PREFIX)/gcc-install: $(PREFIX)/relibc-freestanding-install | $(PREFIX)/libtool-install $(FSTOOLS_TAG) $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
@echo "\033[1;36;49mBuilding gcc-install\033[0m"
rm -rf "$@.partial" "$@-build.partial" "$@"
if [ ! -d "$(ROOT)/$(GCC_TARGET)" ]; then \
echo "\033[1;38;5;196m Incomplete build stages detected. Run 'make prefix' to rebuild the toolchain (gcc-freestanding-install and relibc-freestanding-install must complete first).\033[0m"; \
rm -rf "$(PREFIX)"/gcc-freestanding-install && "$(PREFIX)"/relibc-freestanding-install && \
exit 1; fi
mkdir -p "$@.partial" "$@-build.partial"
cp -r "$(PREFIX)/gcc-freestanding-install/". "$@.partial"
cp -r "$(PREFIX)/relibc-freestanding-install/". "$@.partial"
cp -r "$(PREFIX)/libtool-install/". "$@.partial"
@#TODO: how to make this not conflict with libc?
@# Version-globbed: hardcoding a GCC version here made the rm silently
@# no-op after a toolchain upgrade, leaving the conflicting limits.h.
rm -f "$@.partial/lib/gcc/$(GNU_TARGET)"/*/include/limits.h
# libgcc and freestanding libstdcxx
export PATH="$(ROOT)/$@.partial/bin:$$PATH" && \
$(MAKE) -C "$(ROOT)/$(GCC_TARGET)/build" all-target-libgcc all-target-libstdc++-v3 && \
$(MAKE) -C "$(ROOT)/$(GCC_TARGET)/build" install-target-libgcc install-target-libstdc++-v3 DESTDIR="$(ROOT)/$@-build.partial/usr"
cp -r "$@-build.partial/usr/". "$@.partial"
@#TODO: in riscv64gc libgcc_s.so is a GNU ld script
rm -f "$@.partial"/$(GNU_TARGET)/lib/libgcc_s.so
ln -s libgcc_s.so.1 "$@.partial"/$(GNU_TARGET)/lib/libgcc_s.so
@#TODO: generates wrong lib path for libtool
rm -f "$@.partial"/$(GNU_TARGET)/lib/libstdc++.la
rm -f "$@.partial"/$(GNU_TARGET)/lib/libsupc++.la
# hosted libstdcxx
export PATH="$(ROOT)/$@.partial/bin:$$PATH" && \
export $(PREFIX_CONFIG) "COOKBOOK_HOST_SYSROOT=$(ROOT)/$@.partial" COOKBOOK_CROSS_TARGET=$(HOST_TARGET) && \
rm -rf "$(LIBSTDCXX_TARGET)/stage" && $(REPO_BIN) cook libstdcxx-v3
cp -r "$(LIBSTDCXX_TARGET)/stage/usr/". "$@.partial/$(GNU_TARGET)"
rm -rf "$@-build.partial"
touch "$@.partial"
mv "$@.partial" "$@"
# no longer needed, delete build files to save disk space
rm -rf $(BINUTILS_TARGET) $(LIBTOOL_TARGET) $(GCC_TARGET) $(LIBSTDCXX_TARGET) $(RELIBC_FREESTANDING_TARGET)
endif
# RUST FROM UPSTREAM COMPILER ---------------------------------------------------
ifeq ($(PREFIX_USE_UPSTREAM_RUST_COMPILER),1)
PREFIX_RUST_VERSION_TAG=$(PREFIX)/rustc-version-tag-$(UPSTREAM_RUSTC_VERSION)
$(PREFIX_RUST_VERSION_TAG):
rm -f "$(PREFIX)"/rustc-version-tag-*
rm -f "$(PREFIX)"/rustc-install.tar.xz
rm -f "$(PREFIX)"/cargo-install.tar.xz
rm -f "$(PREFIX)"/rust-std-host-install.tar.xz
rm -f "$(PREFIX)"/rust-std-target-install.tar.xz
rm -f "$(PREFIX)"/rust-src-install.tar.xz:
mkdir -p "$(@D)"
touch $@
$(PREFIX)/rustc-install.tar.xz $(PREFIX)/cargo-install.tar.xz: $(PREFIX)/%-install.tar.xz: | $(PREFIX_RUST_VERSION_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
mkdir -p "$(@D)"
wget --tries=3 --timeout=30 --waitretry=5 -O $@.partial "https://static.rust-lang.org/dist/$(UPSTREAM_RUSTC_VERSION)/$*-nightly-$(HOST_TARGET).tar.xz"
@test -s $@.partial || { echo "Error: download failed or produced empty file: $@"; rm -f $@.partial; exit 1; }
mv $@.partial $@
endif
$(PREFIX)/rust-std-host-install.tar.xz: | $(PREFIX_RUST_VERSION_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
mkdir -p "$(@D)"
wget --tries=3 --timeout=30 --waitretry=5 -O $@.partial "https://static.rust-lang.org/dist/$(UPSTREAM_RUSTC_VERSION)/rust-std-nightly-$(HOST_TARGET).tar.xz"
@test -s $@.partial || { echo "Error: download failed or produced empty file: $@"; rm -f $@.partial; exit 1; }
mv $@.partial $@
endif
$(PREFIX)/rust-std-target-install.tar.xz: | $(PREFIX_RUST_VERSION_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
mkdir -p "$(@D)"
ifeq ($(TARGET),x86_64-unknown-redox)
wget --tries=3 --timeout=30 --waitretry=5 -O $@.partial "https://static.rust-lang.org/dist/$(UPSTREAM_RUSTC_VERSION)/rust-std-nightly-$(TARGET).tar.xz"
@test -s $@.partial || { echo "Error: download failed or produced empty file: $@"; rm -f $@.partial; exit 1; }
mv $@.partial $@
else
touch $@
endif
endif
$(PREFIX)/rust-src-install.tar.xz: | $(PREFIX_RUST_VERSION_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
mkdir -p "$(@D)"
wget --tries=3 --timeout=30 --waitretry=5 -O $@.partial "https://static.rust-lang.org/dist/$(UPSTREAM_RUSTC_VERSION)/rust-src-nightly.tar.xz"
@test -s $@.partial || { echo "Error: download failed or produced empty file: $@"; rm -f $@.partial; exit 1; }
mv $@.partial $@
endif
$(PREFIX)/rust-install: $(PREFIX)/rustc-install.tar.xz $(PREFIX)/cargo-install.tar.xz $(PREFIX)/rust-std-host-install.tar.xz $(PREFIX)/rust-std-target-install.tar.xz $(PREFIX)/rust-src-install.tar.xz
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
@echo "\033[1;36;49mBuilding rust-install\033[0m"
rm -rf "$@.partial" "$@"
mkdir -p "$@.partial"
tar --extract --file "$(PREFIX)/rustc-install.tar.xz" -C "$@.partial" rustc-nightly-$(HOST_TARGET)/rustc/ --strip-components=2
tar --extract --file "$(PREFIX)/cargo-install.tar.xz" --directory "$@.partial" cargo-nightly-$(HOST_TARGET)/cargo/ --strip-components=2
tar --extract --file "$(PREFIX)/rust-std-host-install.tar.xz" --directory "$@.partial" rust-std-nightly-$(HOST_TARGET)/rust-std-$(HOST_TARGET)/ --strip-components=2
tar --extract --file "$(PREFIX)/rust-src-install.tar.xz" --directory "$@.partial" rust-src-nightly/rust-src/ --strip-components=2
ifeq ($(TARGET),x86_64-unknown-redox)
tar --extract --file "$(PREFIX)/rust-std-target-install.tar.xz" --directory "$@.partial" rust-std-nightly-$(TARGET)/rust-std-$(TARGET)/ --strip-components=2
endif
rm -f "$@.partial/manifest.in"
touch "$@.partial"
mv "$@.partial" "$@"
endif
# BUILD RUST ---------------------------------------------------
else
$(PREFIX)/rust-install: | $(PREFIX)/libtool-install $(FSTOOLS_TAG) $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
@echo "\033[1;36;49mBuilding rust-install\033[0m"
rm -rf "$@.partial" "$@"
export PATH="$(ROOT)/$(PREFIX)/libtool-install/bin:$$PATH" \
$(PREFIX_CONFIG) COOKBOOK_HOST_SYSROOT=/usr COOKBOOK_CROSS_TARGET=$(TARGET) && \
$(REPO_BIN) cook host:llvm21 host:rust
cp -r "$(RUST_TARGET)/stage/usr/". "$@.partial"
cp -r "$(LLVM_TARGET)/stage/usr/". "$@.partial"
mv "$@.partial" "$@"
# TODO: Cache from RUST_TARGET is currently not cleared.
# TIP: If you're developing std for rust, remove COOKBOOK_CLEAN_BUILD=true
# at the top of this file so your next rust build reuses the build cache
endif
endif
# BUILD CLANG ---------------------------------------------------
$(PREFIX)/clang-install: | $(PREFIX)/rust-install $(PREFIX)/libtool-install $(FSTOOLS_TAG) $(CONTAINER_TAG)
ifeq ($(PODMAN_BUILD),1)
$(PODMAN_RUN) make $@
else
@echo "\033[1;36;49mBuilding clang-install\033[0m"
rm -rf "$@.partial" "$@"
export PATH="$(ROOT)/$(PREFIX)/libtool-install/bin:$$PATH" \
$(PREFIX_CONFIG) COOKBOOK_HOST_SYSROOT=/usr COOKBOOK_CROSS_TARGET=$(TARGET) && \
$(REPO_BIN) cook host:llvm21 host:clang21 host:lld21
# llvm libraries is already in rust if building
ifeq ($(PREFIX_USE_UPSTREAM_RUST_COMPILER),1)
cp -r "$(LLVM_TARGET)/stage/usr/". "$@.partial"
endif
cp -r "$(LLVM_TARGET)/stage.runtime/usr/". "$@.partial"
cp -r "$(CLANG_TARGET)/stage/usr/". "$@.partial"
cp -r "$(LLD_TARGET)/stage/usr/". "$@.partial"
mv "$@.partial" "$@"
# Propagate the freshly-built host LLVM (which now carries the AMDGPU + NVPTX GPU
# backends per recipes/dev/llvm21) into the redoxer toolchain. The Mesa build
# reads a host llvm-config through bin/x86_64-unknown-redox-llvm-config, which
# execs $COOKBOOK_HOST_SYSROOT/bin/llvm-config (= this toolchain). The toolchain
# ships a downloaded X86-only LLVM, so without this sync mesa's
# dependency('llvm', modules: [... amdgpu ...]) reports amdgpu(missing) and the
# GPU driver build fails. rsync WITHOUT --delete so the toolchain's gcc/rust and
# redox-target files are preserved; only the (same-version, 21.1.2) LLVM
# binaries/libs/headers/cmake are updated to the AMDGPU/NVPTX build.
@REDOXER_TC=$(HOME)/.redoxer/$(TARGET)/toolchain; \
if [ -d "$$REDOXER_TC/bin" ]; then \
rsync -a "$@/bin/llvm-config" "$$REDOXER_TC/bin/llvm-config"; \
rsync -a "$@/lib/" "$$REDOXER_TC/lib/"; \
rsync -a "$@/include/llvm" "$@/include/llvm-c" "$$REDOXER_TC/include/" 2>/dev/null || true; \
echo " [toolchain] synced AMDGPU/NVPTX host LLVM into redoxer toolchain"; \
fi
# no longer needed, delete build files to save disk space
rm -rf $(LLVM_TARGET) $(CLANG_TARGET) $(LLD_TARGET)
endif
endif