From ecc971b4ec6236e4f45b1fc0e8b14132207439f1 Mon Sep 17 00:00:00 2001 From: vasilito Date: Fri, 31 Jul 2026 08:18:46 +0300 Subject: [PATCH] llvm-native: re-architect as a PURE HOST build (fixes libclc host-LLVM) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit llvm-native's job is to supply a COMPLETE host LLVM dev tree (host clang + host static component libs + matching cmake/llvm export) that libclc's find_package(LLVM) and host clang need for Mesa's iris/radeonsi CLC path. The redoxer toolchain ships host clang + libLLVM.so but strips the static libs, so find_package fails — and stubbing them violates the no-stub policy. The recipe was WRONGLY cross-compiling LLVM for the Redox target via cookbook_cmake: that (a) produces host-unusable Redox binaries and (b) fails to link because Redox's libstdc++ lacks symbols LLVM uses (std::random_device etc.). My earlier LLVM_USE_HOST_TOOLS=OFF / tblgen-var / native.cmake patches were all treating symptoms of that wrong architecture. Rewrite: build entirely with the host gcc, targeting the host, exactly like libclc builds its own host prepare_builtins tool — invoke cmake directly (not cookbook_cmake) with /usr/bin/gcc and no CMAKE_SYSTEM_NAME so CROSSCOMPILING is false (LLVM builds one native tblgen with host gcc; no NATIVE sub-project, no Redox-header leak). Drop all Redox build-deps and the llvm21.runtime package dep. Validated: host GCC 16.1.1 configures LLVM 21 and builds llvm-min-tblgen + libLLVMSupport.a/libLLVMTableGen.a cleanly. This is how upstream-style host LLVM tooling should be produced; it supersedes the cross-build patch chain (312659fe21, 5d426d89a7, 872935057c, b2d9a31a4f). --- local/recipes/dev/llvm-native/recipe.toml | 212 +++++++--------------- 1 file changed, 69 insertions(+), 143 deletions(-) diff --git a/local/recipes/dev/llvm-native/recipe.toml b/local/recipes/dev/llvm-native/recipe.toml index 7c498da9fc..c3264064b8 100644 --- a/local/recipes/dev/llvm-native/recipe.toml +++ b/local/recipes/dev/llvm-native/recipe.toml @@ -3,158 +3,84 @@ same_as = "../../../../recipes/dev/llvm21" [build] template = "custom" -dependencies = [ - "llvm21", - "llvm21.runtime", - "llvm21.dev", - "clang21", - "lld21", - "zstd", -] +# PURE HOST build — needs nothing from the Redox cross sysroot. (It shares the +# llvm21 SOURCE via [source] same_as, which is a source relationship, not a +# build dependency.) +dependencies = [] script = """ DYNAMIC_INIT ARCH="$(echo "${TARGET}" | cut -d - -f1)" - -# Save and unset the cross-compile flags DYNAMIC_INIT exports so the host cc -# in the native sub-build (CROSS_TOOLCHAIN_FLAGS_NATIVE below) links against -# the host libc, not the Redox sysroot's relibc — otherwise the native cmake -# try_compile fails with "undefined reference to __libc_start_main". The cross -# build restores them via -DCMAKE_*_FLAGS further down. Mirrors the llvm21 -# recipe, which solved this exact failure. -_SAVED_LDFLAGS="${LDFLAGS:-}" -_SAVED_CFLAGS="${CFLAGS:-}" -_SAVED_CXXFLAGS="${CXXFLAGS:-}" -unset LDFLAGS CFLAGS CXXFLAGS - -# Use /usr (host sysroot) for the native build, NOT $COOKBOOK_TOOLCHAIN (the -# Redox cross sysroot whose libc.a lacks __libc_start_main). -generate_cookbook_cmake_file "$COOKBOOK_HOST_TARGET" "" "/usr" native.cmake - -# The generated native.cmake still inherits CMAKE_*_FLAGS / sysroot from the -# cross toolchain via the cache; CACHE FORCE is required because try_compile -# creates a sub-cache that re-reads the parent values unless explicitly forced. -cat >> native.cmake <<'NATIVE_EOF' - -# Override cross-sysroot flags so the host cc links against the host libc. -set(CMAKE_C_FLAGS "" CACHE STRING "" FORCE) -set(CMAKE_CXX_FLAGS "" CACHE STRING "" FORCE) -set(CMAKE_CXX_FLAGS_DEBUG "" CACHE STRING "" FORCE) -set(CMAKE_CXX_FLAGS_RELEASE "" CACHE STRING "" FORCE) -set(CMAKE_C_FLAGS_DEBUG "" CACHE STRING "" FORCE) -set(CMAKE_C_FLAGS_RELEASE "" CACHE STRING "" FORCE) -set(CMAKE_LDFLAGS "" CACHE STRING "" FORCE) -set(CMAKE_LDFLAGS_DEBUG "" CACHE STRING "" FORCE) -set(CMAKE_LDFLAGS_RELEASE "" CACHE STRING "" FORCE) -set(CMAKE_EXE_LINKER_FLAGS "" CACHE STRING "" FORCE) -set(CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "" FORCE) -set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "" CACHE STRING "" FORCE) -set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "" CACHE STRING "" FORCE) -set(CMAKE_SYSROOT "" CACHE STRING "" FORCE) -set(CMAKE_FIND_ROOT_PATH "" CACHE STRING "" FORCE) -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM "NEVER" CACHE STRING "" FORCE) -set(ENV{LDFLAGS} "") -set(ENV{CFLAGS} "") -set(ENV{CXXFLAGS} "") -NATIVE_EOF - case "${ARCH}" in - x86 | x86_64) LLVM_TARGETS_TO_BUILD="X86";; - aarch64) LLVM_TARGETS_TO_BUILD="AArch64";; - riscv64gc) LLVM_TARGETS_TO_BUILD="RISCV";; + x86 | x86_64) LLVM_HOST_ARCH="X86";; + aarch64) LLVM_HOST_ARCH="AArch64";; + riscv64gc) LLVM_HOST_ARCH="RISCV";; esac -# The *-tblgen references below must be VERSION-MATCHED to this LLVM source -# tree. cookbook does not export COOKBOOK_HOST_SYSROOT, so an unset value -# collapses them to "/bin/{llvm,clang}-tblgen" — the rolling distro LLVM (now -# 22), whose -gen-opt-parser-defs backend requires a `SubCommand` class that -# LLVM 21's OptParser.td does not define. Point at the redoxer toolchain's -# host-runnable LLVM 21.1.2 tblgen, matching the clang21/lld21 recipes. -export COOKBOOK_HOST_SYSROOT="${COOKBOOK_HOST_SYSROOT:-${HOME}/.redoxer/${TARGET}/toolchain}" +# ============================================================================ +# llvm-native is a PURE HOST build of LLVM/Clang/LLD 21. +# +# Its whole purpose is to supply a COMPLETE host LLVM dev tree (host-runnable +# clang + host static component libs + a matching cmake/llvm export) that +# libclc's `find_package(LLVM)` and host `clang` need to compile the OpenCL-C +# builtins bitcode Mesa's iris/radeonsi CLC path consumes. The redoxer +# toolchain ships a host clang + libLLVM.so but STRIPS the static component +# libs, so its LLVMExports references files that don't exist and find_package +# fails — and faking them with stub archives violates the no-stub policy. +# +# It must NOT be cross-compiled for Redox (the previous mistake): a +# Redox-target LLVM (a) produces binaries that can't run on the build host and +# (b) fails to LINK because Redox's libstdc++ lacks symbols LLVM uses +# (e.g. std::random_device). So we build entirely with the HOST gcc, targeting +# the host, exactly the way libclc builds its own host prepare_builtins tool. +# +# We deliberately do NOT use cookbook_cmake (which configures a Redox +# cross-build). We invoke cmake directly with the host gcc and no +# CMAKE_SYSTEM_NAME, so CMAKE_CROSSCOMPILING is false: LLVM builds its own +# native tblgen once (host gcc → no Redox-header leak) and there is no NATIVE +# external sub-project. +# ============================================================================ -COOKBOOK_CMAKE_FLAGS+=( - -DLLVM_ENABLE_PROJECTS="clang;lld" - -DLLVM_BUILD_LLVM_DYLIB=On - -DLLVM_LINK_LLVM_DYLIB=On - -DLLVM_INCLUDE_UTILS=On - -DLLVM_INSTALL_UTILS=On - -DLLVM_TARGETS_TO_BUILD="$LLVM_TARGETS_TO_BUILD" - -DLLVM_ENABLE_ZLIB=Off - -DLLVM_USE_STATIC_ZSTD=On - -DLLVM_ENABLE_LIBXML2=Off - -DCLANG_LINK_CLANG_DYLIB=ON - -DLIBCLANG_BUILD_STATIC=1 - -DCROSS_TOOLCHAIN_FLAGS_NATIVE="-DCMAKE_TOOLCHAIN_FILE=$(realpath native.cmake)" - -DBUILD_SHARED_LIBS=False - -DLLVM_BUILD_EXAMPLES=Off - -DLLVM_BUILD_TESTS=Off - -DLLVM_DEFAULT_TARGET_TRIPLE="${TARGET}" - -DLLVM_ENABLE_LTO=Off - -DLLVM_ENABLE_RTTI=On - -DLLVM_ENABLE_THREADS=On - -DLLVM_INCLUDE_EXAMPLES=Off - -DLLVM_INCLUDE_TESTS=Off - # OFF on purpose: this recipe PROVIDES host-runnable, version-matched - # tblgens via LLVM_TABLEGEN/CLANG_TABLEGEN below (the redoxer toolchain's - # LLVM 21.1.2). LLVM_OPTIMIZED_TABLEGEN=On would build a second optimized - # native tblgen instead of using them. Off => LLVM uses what we provide. - -DLLVM_OPTIMIZED_TABLEGEN=Off - # OFF is REQUIRED here. LLVM_USE_HOST_TOOLS defaults ON when cross-compiling - # and makes llvm/CMakeLists.txt create the NATIVE external project - # (llvm_create_cross_target LLVM NATIVE), a full second host LLVM build that - # inherits the Redox cross flags and dies compiling native llvm-config/etc. - # We already supply host-runnable, version-matched tblgens via - # LLVM_TABLEGEN/CLANG_TABLEGEN (the only native tools a cross-build needs), - # so the NATIVE project is pure waste. OFF => no native sub-build; LLVM uses - # the provided tblgens for .inc generation. - -DLLVM_USE_HOST_TOOLS=OFF - -DLLVM_TARGET_ARCH=$ARCH - -DLLVM_TOOLS_INSTALL_DIR=bin - -DLLVM_UTILS_INSTALL_DIR=bin - -DUNIX=1 - # CRITICAL: the cache vars LLVM/Clang read to SKIP building a native tblgen - # when cross-compiling are LLVM_TABLEGEN / CLANG_TABLEGEN (see - # llvm/cmake/modules/TableGen.cmake: "Native TableGen executable. Saves - # building one when cross-compiling"). The *_TABLEGEN_EXE names used - # previously are NOT read by a from-scratch LLVM build, so LLVM built its - # own native tblgen via the CROSS_TOOLCHAIN_FLAGS_NATIVE sub-build — which - # ran the HOST gcc against the Redox relibc headers leaked through - # CMAKE_CXX_FLAGS and died on host/redox conflicts - # (__deprecated/__noreturn undeclared, duplicate div_t). Passing the - # correct var names makes LLVM use the provided host tblgens (LLVM 21.1.2) - # and skip the native sub-build entirely. (lld21/clang21 build against a - # PREBUILT llvm and locate tblgen via find_program on LLVM_TABLEGEN_EXE — - # a different cache var owned by those projects — so they are correct.) - -DLLVM_TABLEGEN=${COOKBOOK_HOST_SYSROOT}/bin/llvm-tblgen - -DCLANG_TABLEGEN=${COOKBOOK_HOST_SYSROOT}/bin/clang-tblgen -) +# Drop every cross-compile flag DYNAMIC_INIT exported so the host gcc never +# sees the Redox sysroot / relibc. +unset LDFLAGS CFLAGS CXXFLAGS CPPFLAGS COOKBOOK_SOURCE="$COOKBOOK_SOURCE/llvm" -# Restore the cross-compile flags for the CROSS build via cmake vars rather -# than the environment: an exported LDFLAGS leaks into the native try_compile -# and re-introduces the Redox libc link failure. (Native.cmake above keeps the -# host sub-build clean.) -if [ -n "${_SAVED_LDFLAGS}" ]; then - COOKBOOK_CMAKE_FLAGS+=(-DCMAKE_EXE_LINKER_FLAGS="${_SAVED_LDFLAGS}") - COOKBOOK_CMAKE_FLAGS+=(-DCMAKE_SHARED_LINKER_FLAGS="${_SAVED_LDFLAGS}") -fi -if [ -n "${_SAVED_CFLAGS}" ]; then - COOKBOOK_CMAKE_FLAGS+=(-DCMAKE_C_FLAGS="${_SAVED_CFLAGS}") -fi -# LLVM 21 REQUIRES C++17 (its headers use std::remove_reference_t, std::size, -# std::shared_timed_mutex, etc.). The main build gets -std=gnu++17 from LLVM's -# own CMAKE_CXX_STANDARD=17, appended after CMAKE_CXX_FLAGS so it wins — but the -# CROSS_TOOLCHAIN_FLAGS_NATIVE sub-build (native llvm-tblgen) inherits -# CMAKE_CXX_FLAGS with a DIFFERENT flag order where a stale "--std=gnu++11" -# would win, breaking ("'_M_rwlock' was not declared"). Pass -# gnu++17 here so no target can regress to C++11 regardless of flag order. -if [ -n "${_SAVED_CXXFLAGS}" ]; then - COOKBOOK_CMAKE_FLAGS+=(-DCMAKE_CXX_FLAGS="--std=gnu++17 ${_SAVED_CXXFLAGS}") -else - COOKBOOK_CMAKE_FLAGS+=(-DCMAKE_CXX_FLAGS="--std=gnu++17") -fi +"${COOKBOOK_CMAKE}" "${COOKBOOK_SOURCE}" \ + -G Ninja \ + -Wno-dev \ + -DCMAKE_C_COMPILER=/usr/bin/gcc \ + -DCMAKE_CXX_COMPILER=/usr/bin/g++ \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DLLVM_ENABLE_PROJECTS="clang;lld" \ + -DLLVM_BUILD_LLVM_DYLIB=On \ + -DLLVM_LINK_LLVM_DYLIB=On \ + -DLLVM_INCLUDE_UTILS=On \ + -DLLVM_INSTALL_UTILS=On \ + -DLLVM_TARGETS_TO_BUILD="$LLVM_HOST_ARCH" \ + -DLLVM_ENABLE_ZLIB=Off \ + -DLLVM_ENABLE_ZSTD=Off \ + -DLLVM_ENABLE_LIBXML2=Off \ + -DLLVM_ENABLE_WERROR=Off \ + -DCLANG_LINK_CLANG_DYLIB=On \ + -DLIBCLANG_BUILD_STATIC=1 \ + -DBUILD_SHARED_LIBS=False \ + -DLLVM_BUILD_EXAMPLES=Off \ + -DLLVM_BUILD_TESTS=Off \ + -DLLVM_INCLUDE_EXAMPLES=Off \ + -DLLVM_INCLUDE_TESTS=Off \ + -DLLVM_DEFAULT_TARGET_TRIPLE="${TARGET}" \ + -DLLVM_ENABLE_LTO=Off \ + -DLLVM_ENABLE_RTTI=On \ + -DLLVM_ENABLE_THREADS=On \ + -DLLVM_TARGET_ARCH="$LLVM_HOST_ARCH" \ + -DLLVM_TOOLS_INSTALL_DIR=bin \ + -DLLVM_UTILS_INSTALL_DIR=bin \ + -DUNIX=1 -cookbook_cmake +"${COOKBOOK_NINJA}" -j"${COOKBOOK_MAKE_JOBS}" +DESTDIR="${COOKBOOK_STAGE}" "${COOKBOOK_NINJA}" install # Create unprefixed symlinks for native use for tool in clang clang++ clang-cpp clang-cl clang-check clang-format clang-tidy \ @@ -184,8 +110,8 @@ rm -f "${COOKBOOK_STAGE}"/usr/lib/*.la """ [package] -description = "Native LLVM/Clang/LLD 21 toolchain for Red Bear OS" -dependencies = ["llvm21.runtime"] +description = "Native (host) LLVM/Clang/LLD 21 toolchain for Red Bear OS — host build-time tool tree consumed by libclc; not shipped to the target image" +dependencies = [] [[optional-packages]] name = "dev"