22dceb4e8a
Install used an ABSOLUTE CMAKE_INSTALL_PREFIX (${COOKBOOK_STAGE}/usr) together
with DESTDIR=${COOKBOOK_STAGE}/stage, so everything double-nested under
stage.tmp/<abs>/stage.tmp/usr/... and libclc.pc/.bc never reached the expected
paths. Use the standard pattern: relative prefix /usr + DESTDIR=${COOKBOOK_STAGE}
(libclc.pc gets prefix=/usr, resolved downstream via PKG_CONFIG_SYSROOT_DIR);
drop the stage-flatten hack. Also relocate libclc.pc from share/pkgconfig
(upstream's DATADIR) to lib/pkgconfig (cookbook convention mesa looks up).
All 2610 GPU bitcode files already generate + install correctly.
241 lines
12 KiB
TOML
241 lines
12 KiB
TOML
[package]
|
|
name = "libclc"
|
|
# Red Bear OS internal libclc. Upstream is llvm-project's libclc
|
|
# (https://github.com/llvm/llvm-project/tree/main/libclc). The source
|
|
# is vendored from the same revision as llvm21 (redox-2025-10-03).
|
|
# The version follows the Red Bear OS branch per local/AGENTS.md.
|
|
version = "0.3.1"
|
|
description = "libclc — Red Bear OS port of the OpenCL C library requirements (amdgcn, r600, spirv, generic targets). Provides the .bc bitcode files Mesa's clc tool consumes for hardware GPU drivers (iris, radeonsi, llvmpipe)."
|
|
|
|
[source]
|
|
# Vendored from the same revision as llvm21 / clang21.
|
|
git = "https://gitlab.redox-os.org/redox-os/llvm-project.git"
|
|
upstream = "https://github.com/llvm/llvm-project.git"
|
|
branch = "redox-2025-10-03"
|
|
path_in_repo = "libclc"
|
|
shallow_clone = true
|
|
|
|
[build]
|
|
template = "custom"
|
|
# libclc's *native* build needs a COMPLETE HOST LLVM dev tree: a host-runnable
|
|
# clang + llvm-as/opt/llc/llvm-link plus find_package(LLVM)'s LLVMConfig.cmake,
|
|
# LLVMExports.cmake AND the static component libs they reference. The redoxer
|
|
# runtime toolchain (COOKBOOK_TOOLCHAIN) ships only libLLVM.so + clang — its
|
|
# LLVMExports.cmake references static libs that are not present, so
|
|
# find_package(LLVM) fails ("file does not exist"). The cross llvm21.dev is the
|
|
# WRONG LLVM (its cmake/libs target Redox, not the host).
|
|
#
|
|
# llvm-native is exactly the missing piece: a native (host) LLVM/Clang/LLD 21
|
|
# build (same redox-2025-10-03 revision as llvm21/clang21). Its packages split
|
|
# as: main = leftover host tools (diagtool, lli, FileCheck, cc/c++ …);
|
|
# .dev = usr/lib/cmake/llvm/**, host libLLVM*.a + includes (for find_package);
|
|
# .runtime = usr/bin/clang*, usr/bin/lld*, usr/bin/llvm-*, libLLVM*.so
|
|
# (the host CLANG libclc RUNS to compile the OpenCL-C builtins to bitcode).
|
|
#
|
|
# ALL of it is BUILD-ONLY: libclc's shipped artifact is the .bc/.pc files that
|
|
# Mesa consumes at runtime, never clang. So the whole host toolchain goes in
|
|
# dev-dependencies (staged into the build sysroot, NOT pulled into the image).
|
|
# We must include .runtime explicitly — the .dev -> .runtime package link does
|
|
# NOT transitively stage .runtime at build time, so without it the host clang
|
|
# is absent and the build errors "host clang not found". We deliberately do NOT
|
|
# pull llvm21.dev (the Redox-cross LLVM) — it would drop a SECOND, conflicting
|
|
# usr/lib/cmake/llvm into the sysroot and find_package would pick the wrong one.
|
|
# NOTE: llvm-native (main) MUST be in `dependencies`, not dev-dependencies:
|
|
# the cookbook's cook-tree (src/cook/tree.rs) only follows `dependencies` when
|
|
# resolving what to COOK (--with-package-deps), so a dev-only dep is staged but
|
|
# never built -> "stage.pkgar No such file or directory". Cooking llvm-native
|
|
# (main) produces ALL its subpackage pkgars (main + .dev + .runtime); we then
|
|
# stage the two we need as dev-dependencies (build-only).
|
|
dependencies = [
|
|
"llvm-native",
|
|
]
|
|
dev-dependencies = [
|
|
"llvm-native.dev",
|
|
"llvm-native.runtime",
|
|
]
|
|
script = '''
|
|
DYNAMIC_INIT
|
|
ARCH="$(echo "${TARGET}" | cut -d - -f1)"
|
|
|
|
# libclc is built with the HOST clang (not the cross-compiler):
|
|
# it produces .bc bitcode files that are architecture-independent
|
|
# for the GPU targets Mesa cares about (amdgcn, r600, spirv,
|
|
# generic). The output is then consumed at runtime by Mesa's clc
|
|
# tool via the dependency('libclc') pkg-config lookup.
|
|
|
|
# Save the cross-compile environment so we can use the HOST
|
|
# toolchain (Clang) to compile OpenCL kernels to bitcode.
|
|
_SAVED_LDFLAGS="${LDFLAGS:-}"
|
|
_SAVED_CFLAGS="${CFLAGS:-}"
|
|
_SAVED_CXXFLAGS="${CXXFLAGS:-}"
|
|
_SAVED_CPPFLAGS="${CPPFLAGS:-}"
|
|
unset LDFLAGS CFLAGS CXXFLAGS CPPFLAGS
|
|
|
|
# Resolve the HOST LLVM prefix provided by llvm-native (+ .dev), staged into
|
|
# the cross sysroot by our build-dependencies. pkgar extracts packages as-is,
|
|
# so llvm-native's usr/ tree lands under ${COOKBOOK_SYSROOT}/usr/. Everything
|
|
# libclc's native build needs is under here: the host clang/llvm-* binaries
|
|
# (usr/bin), and find_package(LLVM)'s complete cmake tree + static libs
|
|
# (usr/lib/cmake/llvm, usr/lib/libLLVM*.a).
|
|
HOST_LLVM_PREFIX="${COOKBOOK_SYSROOT}/usr"
|
|
HOST_LLVM_CMAKE="${HOST_LLVM_PREFIX}/lib/cmake/llvm"
|
|
|
|
# Pick the host clang: llvm-native installs an unprefixed `clang` symlink; fall
|
|
# back to clang-21 if only the versioned name is present.
|
|
if [ -x "${HOST_LLVM_PREFIX}/bin/clang" ]; then
|
|
HOST_CLANG="${HOST_LLVM_PREFIX}/bin/clang"
|
|
elif [ -x "${HOST_LLVM_PREFIX}/bin/clang-21" ]; then
|
|
HOST_CLANG="${HOST_LLVM_PREFIX}/bin/clang-21"
|
|
else
|
|
echo "libclc: ERROR — host clang not found under ${HOST_LLVM_PREFIX}/bin" >&2
|
|
echo "libclc: is the 'llvm-native' build-dependency staged? ls:" >&2
|
|
ls -la "${HOST_LLVM_PREFIX}/bin" 2>/dev/null | grep -i clang >&2 || true
|
|
exit 1
|
|
fi
|
|
if [ ! -f "${HOST_LLVM_CMAKE}/LLVMConfig.cmake" ]; then
|
|
echo "libclc: ERROR — host LLVMConfig.cmake not found at ${HOST_LLVM_CMAKE}" >&2
|
|
echo "libclc: is the 'llvm-native.dev' build-dependency staged?" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# The C++ compiler for prepare_builtins MUST be the clang++ driver, not clang:
|
|
# cmake links the CXX target with CMAKE_CXX_COMPILER, and the plain `clang`
|
|
# (C) driver does NOT add the C++ runtime, so linking prepare_builtins against
|
|
# libLLVM.so fails "libstdc++.so.6: DSO missing from command line"
|
|
# (undefined std::__cxx11::basic_string::_M_assign). clang++ links libstdc++.
|
|
if [ -x "${HOST_LLVM_PREFIX}/bin/clang++" ]; then
|
|
HOST_CLANGXX="${HOST_LLVM_PREFIX}/bin/clang++"
|
|
elif [ -x "${HOST_LLVM_PREFIX}/bin/clang++-21" ]; then
|
|
HOST_CLANGXX="${HOST_LLVM_PREFIX}/bin/clang++-21"
|
|
else
|
|
echo "libclc: ERROR — host clang++ not found under ${HOST_LLVM_PREFIX}/bin" >&2
|
|
ls -la "${HOST_LLVM_PREFIX}/bin" 2>/dev/null | grep -i clang >&2 || true
|
|
exit 1
|
|
fi
|
|
|
|
# Generate a NATIVE toolchain file. We can't use cookbook_cmake
|
|
# because that targets the cross sysroot; libclc needs the host.
|
|
generate_cookbook_cmake_file "${COOKBOOK_HOST_TARGET}" "" "${HOST_LLVM_PREFIX}" native_libclc.cmake
|
|
|
|
# Override CMAKE_C/CXX/ASM_COMPILER etc. to point at llvm-native's HOST clang
|
|
# and llvm-* tools in the sysroot, and LLVM_DIR at llvm-native's complete host
|
|
# cmake tree (the whole point of depending on llvm-native).
|
|
cat >> native_libclc.cmake <<NATIVE_EOF
|
|
set(CMAKE_C_COMPILER "${HOST_CLANG}" CACHE FILEPATH "" FORCE)
|
|
set(CMAKE_CXX_COMPILER "${HOST_CLANGXX}" CACHE FILEPATH "" FORCE)
|
|
set(CMAKE_ASM_COMPILER "${HOST_CLANG}" CACHE FILEPATH "" FORCE)
|
|
set(CMAKE_AR "${HOST_LLVM_PREFIX}/bin/llvm-ar" CACHE FILEPATH "" FORCE)
|
|
set(CMAKE_NM "${HOST_LLVM_PREFIX}/bin/llvm-nm" CACHE FILEPATH "" FORCE)
|
|
set(CMAKE_RANLIB "${HOST_LLVM_PREFIX}/bin/llvm-ranlib" CACHE FILEPATH "" FORCE)
|
|
set(CMAKE_C_FLAGS_INIT "" CACHE STRING "" FORCE)
|
|
set(CMAKE_CXX_FLAGS_INIT "" CACHE STRING "" FORCE)
|
|
set(CMAKE_EXE_LINKER_FLAGS_INIT "" CACHE STRING "" FORCE)
|
|
set(CMAKE_SHARED_LINKER_FLAGS_INIT "" CACHE STRING "" FORCE)
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM "BYPASS" CACHE STRING "" FORCE)
|
|
set(LLVM_DIR "${HOST_LLVM_CMAKE}" CACHE PATH "" FORCE)
|
|
set(LIBCLC_STANDALONE_BUILD TRUE CACHE BOOL "" FORCE)
|
|
NATIVE_EOF
|
|
|
|
# Run cmake with the host-native toolchain. LIBCLC_TARGETS_TO_BUILD
|
|
# is the list of GPU targets Mesa consumes. The target-name syntax
|
|
# in upstream libclc is `<triple>--` (double-dash suffix for the
|
|
# unspecified-ABI variant) plus the Mesa-specific `amdgcn-mesa-mesa3d`
|
|
# for the Mesa3D frontend. Targets not consumed by Mesa (ptx-nvidiacl
|
|
# for NVIDIA, clspv for Vulkan-SPIR-V) are excluded. The full set
|
|
# covers all gallium drivers Mesa 26.1.4 supports via the clc tool:
|
|
# r600 -> r600 (Southern Islands / Evergreen)
|
|
# amdgcn-- -> GCN GFX6..GFX12 (default-ABI)
|
|
# amdgcn--amdhsa -> GCN with HSA runtime
|
|
# amdgcn-mesa-mesa3d -> GCN via the Mesa3D-specific path
|
|
# The `spirv` target is handled by Mesa's own clc tool (not libclc
|
|
# bitcode); libclc's spirv files are used for mesa's SPIR-V codegen
|
|
# in clc, but the .bc files themselves are produced by Mesa's clc.
|
|
COOKBOOK_CMAKE_FLAGS+=(
|
|
-DCMAKE_TOOLCHAIN_FILE="$(realpath native_libclc.cmake)"
|
|
-DCMAKE_BUILD_TYPE=Release
|
|
-DLLVM_DIR="${HOST_LLVM_CMAKE}"
|
|
-DLIBCLC_STANDALONE_BUILD=TRUE
|
|
-DLIBCLC_TARGETS_TO_BUILD="r600--;amdgcn--;amdgcn--amdhsa;amdgcn-mesa-mesa3d"
|
|
-DENABLE_RUNTIME_SUBNORMAL=OFF
|
|
-DCMAKE_INSTALL_PREFIX=/usr
|
|
-DCMAKE_INSTALL_LIBDIR=lib
|
|
-DCMAKE_INSTALL_INCLUDEDIR=include
|
|
-DCMAKE_INSTALL_DATADIR=share
|
|
-DLLVM_TARGETS_TO_BUILD="$ARCH"
|
|
-G Ninja
|
|
-Wno-dev
|
|
)
|
|
|
|
# Source dir is the path_in_repo subdir of the cloned llvm-project. This
|
|
# cookbook does not extract path_in_repo into COOKBOOK_SOURCE — it clones the
|
|
# whole llvm-project there — so CMake was pointed at the repo root and failed
|
|
# with "source directory does not appear to contain CMakeLists.txt". Descend
|
|
# into the libclc subdir when the whole repo was cloned (mirrors how the clang21
|
|
# recipe does COOKBOOK_SOURCE/clang); if path_in_repo already left the subdir at
|
|
# the root, use it as-is.
|
|
if [ -f "${COOKBOOK_SOURCE}/libclc/CMakeLists.txt" ]; then
|
|
COOKBOOK_SOURCE="${COOKBOOK_SOURCE}/libclc"
|
|
fi
|
|
"${COOKBOOK_CMAKE}" "${COOKBOOK_SOURCE}" "${COOKBOOK_CMAKE_FLAGS[@]}"
|
|
|
|
# In LIBCLC_STANDALONE_BUILD mode, the bitcode-generation custom commands invoke
|
|
# the just-built host tool by BARE name (`prepare_builtins -o foo.bc ...`), not
|
|
# a path — so with `.` absent from PATH they fail "prepare_builtins: command not
|
|
# found". prepare_builtins is built into the build dir (the CWD here), so put it
|
|
# on PATH for the ninja run.
|
|
export PATH="$(pwd):${PATH}"
|
|
"${COOKBOOK_NINJA}" -j"${COOKBOOK_MAKE_JOBS}"
|
|
# Standard install: RELATIVE prefix (/usr, set in COOKBOOK_CMAKE_FLAGS) +
|
|
# DESTDIR=${COOKBOOK_STAGE} -> files land at ${COOKBOOK_STAGE}/usr/... and the
|
|
# generated libclc.pc carries prefix=/usr, which the downstream mesa build
|
|
# resolves via PKG_CONFIG_SYSROOT_DIR. (The previous absolute prefix +
|
|
# DESTDIR/stage double-nested everything under
|
|
# stage.tmp/<abs>/stage.tmp/usr/... so libclc.pc was never at the expected
|
|
# path.)
|
|
DESTDIR="${COOKBOOK_STAGE}" "${COOKBOOK_NINJA}" install
|
|
|
|
# Restore the cross-compile env for any subsequent (cross) steps. The native
|
|
# cmake/ninja above MUST run with the clean (unset) env, so this restore is
|
|
# placed AFTER the build, not before it.
|
|
export LDFLAGS="$_SAVED_LDFLAGS"
|
|
export CFLAGS="$_SAVED_CFLAGS"
|
|
export CXXFLAGS="$_SAVED_CXXFLAGS"
|
|
export CPPFLAGS="$_SAVED_CPPFLAGS"
|
|
|
|
# Mesa's clc tool expects the .bc files at <libexecdir>/clc where
|
|
# libexecdir is <prefix>/share/clc (per the libclc.pc.in template).
|
|
# The cmake install above places them at $COOKBOOK_STAGE/usr/share/clc
|
|
# which is the right path; no further action needed.
|
|
|
|
# Upstream libclc installs libclc.pc under share/pkgconfig (its DATADIR);
|
|
# relocate it to lib/pkgconfig, the cookbook convention that mesa's
|
|
# dependency('libclc') pkg-config lookup uses.
|
|
if [ -f "${COOKBOOK_STAGE}/usr/share/pkgconfig/libclc.pc" ] \
|
|
&& [ ! -f "${COOKBOOK_STAGE}/usr/lib/pkgconfig/libclc.pc" ]; then
|
|
mkdir -p "${COOKBOOK_STAGE}/usr/lib/pkgconfig"
|
|
mv "${COOKBOOK_STAGE}/usr/share/pkgconfig/libclc.pc" \
|
|
"${COOKBOOK_STAGE}/usr/lib/pkgconfig/libclc.pc"
|
|
fi
|
|
|
|
if [ ! -f "${COOKBOOK_STAGE}/usr/lib/pkgconfig/libclc.pc" ]; then
|
|
echo "libclc: ERROR — install did not produce libclc.pc" >&2
|
|
echo "libclc: expected at ${COOKBOOK_STAGE}/usr/lib/pkgconfig/libclc.pc" >&2
|
|
echo "libclc: check that upstream libclc CMakeLists.txt installs pkgconfig files" >&2
|
|
exit 1
|
|
fi
|
|
if [ ! -d "${COOKBOOK_STAGE}/usr/share/clc" ]; then
|
|
echo "libclc: ERROR — install did not produce .bc files under usr/share/clc" >&2
|
|
exit 1
|
|
fi
|
|
if ! ls "${COOKBOOK_STAGE}/usr/share/clc"/*.bc >/dev/null 2>&1; then
|
|
echo "libclc: ERROR — usr/share/clc contains no .bc bitcode files" >&2
|
|
exit 1
|
|
fi
|
|
'''
|
|
|
|
[[optional-packages]]
|
|
name = "dev"
|
|
files = [
|
|
"usr/include/**",
|
|
]
|