Inside the Flatpak the bundled toolchain compiled every bootstrap object, then glslang's configure failed its test link with `unable to find library -lc++`. clang searches its per-target runtime directory (lib/<triple>) and the system library paths for libc++, not <prefix>/lib, so with the classic layout a toolchain outside /usr needs the search path spelled out, just as its loader needs the rpath. LibcxxLinkFlags and build.sh now emit both, the same pair an explicit CRAFTER_BUILD_LIBCXX_DIR already got. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
127 lines
5.6 KiB
Shell
Executable file
127 lines
5.6 KiB
Shell
Executable file
#!/bin/sh
|
|
#SPDX-License-Identifier: LGPL-3.0-only
|
|
#SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
|
|
|
# Bootstrap: compile crafter-build by hand, without crafter-build. The
|
|
# self-host build through project.cpp follows (`./bin/crafter-build`).
|
|
set -eu
|
|
|
|
# The toolchain. CRAFTER_BUILD_LLVM_DIR names an LLVM prefix (the Flatpak
|
|
# sets /app); otherwise the tools come from PATH. The same rule the built
|
|
# binary applies at run time (Crafter.Build:Toolchain).
|
|
if [ -n "${CRAFTER_BUILD_LLVM_DIR:-}" ]; then
|
|
CXX="$CRAFTER_BUILD_LLVM_DIR/bin/clang++"
|
|
CC="$CRAFTER_BUILD_LLVM_DIR/bin/clang"
|
|
AR="$CRAFTER_BUILD_LLVM_DIR/bin/llvm-ar"
|
|
LLVM_CONFIG="$CRAFTER_BUILD_LLVM_DIR/bin/llvm-config"
|
|
# A prefix other than the system one keeps its libc++ off both the
|
|
# linker's search path (clang looks in lib/<triple> and the system dirs,
|
|
# not <prefix>/lib) and the loader's; -L and an rpath cover the two.
|
|
if [ "$CRAFTER_BUILD_LLVM_DIR" != /usr ]; then
|
|
LIBCXX_LINK_FLAGS="-L$CRAFTER_BUILD_LLVM_DIR/lib -Wl,-rpath,$CRAFTER_BUILD_LLVM_DIR/lib"
|
|
else
|
|
LIBCXX_LINK_FLAGS=""
|
|
fi
|
|
if [ -f "$CRAFTER_BUILD_LLVM_DIR/share/libc++/v1/std.cppm" ]; then
|
|
STD_CPPM="$CRAFTER_BUILD_LLVM_DIR/share/libc++/v1/std.cppm"
|
|
else
|
|
STD_CPPM=/usr/share/libc++/v1/std.cppm
|
|
fi
|
|
else
|
|
CXX=clang++
|
|
CC=clang
|
|
AR=llvm-ar
|
|
LLVM_CONFIG=llvm-config
|
|
LIBCXX_LINK_FLAGS=""
|
|
STD_CPPM=/usr/share/libc++/v1/std.cppm
|
|
fi
|
|
|
|
# The version baked into the binary: the environment (CI sets it from the
|
|
# tag), else the nearest tag, else a development marker. `latest` is the
|
|
# rolling CI tag and never a version.
|
|
VERSION="${CRAFTER_BUILD_VERSION:-$(git describe --tags --always --dirty --exclude=latest 2>/dev/null || echo 0.0.0-dev)}"
|
|
|
|
mkdir -p build bin lib share/crafter-build share/crafter-build/wasi-runtime
|
|
|
|
cp wasi-runtime/runtime.js share/crafter-build/wasi-runtime/
|
|
cp wasi-runtime/index.html.in share/crafter-build/wasi-runtime/
|
|
|
|
# Partition order is the import order: every unit is listed before the
|
|
# units that import it, and the umbrella last.
|
|
PARTITIONS="Toolchain Shader Platform Interface Implementation External Clang Test Lint Progress Asset"
|
|
|
|
cp interfaces/Crafter.Build.cppm share/crafter-build/
|
|
for p in $PARTITIONS; do
|
|
cp "interfaces/Crafter.Build-$p.cppm" share/crafter-build/
|
|
done
|
|
|
|
if [ ! -d build/glslang/.git ]; then
|
|
git clone --depth 1 https://github.com/KhronosGroup/glslang.git build/glslang
|
|
fi
|
|
|
|
current_dir=$(pwd)
|
|
|
|
cd build/glslang
|
|
cmake -B build \
|
|
-DCMAKE_C_COMPILER="$CC" \
|
|
-DCMAKE_CXX_COMPILER="$CXX" \
|
|
-DCMAKE_CXX_FLAGS="-stdlib=libc++" \
|
|
-DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++ $LIBCXX_LINK_FLAGS" \
|
|
-DCMAKE_SHARED_LINKER_FLAGS="-stdlib=libc++ $LIBCXX_LINK_FLAGS" \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY="$current_dir/build" \
|
|
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY="$current_dir/build" \
|
|
-DENABLE_OPT=OFF
|
|
cmake --build build --config Release
|
|
cd ../../
|
|
|
|
MARCH="${CRAFTER_BUILD_MARCH:-native}"
|
|
MTUNE="${CRAFTER_BUILD_MTUNE:-native}"
|
|
# The bootstrap targets the toolchain's own triple: x86_64-pc-linux-gnu on
|
|
# glibc distros, x86_64-unknown-linux-gnu for the bundled LLVM,
|
|
# x86_64-alpine-linux-musl on Alpine. Override with CRAFTER_BUILD_TARGET.
|
|
TARGET="${CRAFTER_BUILD_TARGET:-$("$CXX" -print-target-triple)}"
|
|
TARGET_DEFINE="CRAFTER_BUILD_CONFIGURATION_TARGET_$(printf '%s' "$TARGET" | tr - _)"
|
|
|
|
# Crafter.Build-Lint includes libclang's clang-c/Index.h. glibc distros keep
|
|
# it in /usr/include; other prefixes keep it under their own include dir, so
|
|
# ask llvm-config and add the dir when it is not already on the default path
|
|
# (never add /usr/include itself: that breaks libc++'s #include_next).
|
|
LLVM_INCDIR="$("$LLVM_CONFIG" --includedir 2>/dev/null || true)"
|
|
case "$LLVM_INCDIR" in ""|/usr/include) LLVM_INCFLAG="" ;; *) LLVM_INCFLAG="-I$LLVM_INCDIR" ;; esac
|
|
|
|
common_options="--target=$TARGET -stdlib=libc++ -I./build/glslang $LLVM_INCFLAG -std=c++26 -O3 -march=$MARCH -mtune=$MTUNE -fprebuilt-module-path=./build -D $TARGET_DEFINE -D CRAFTER_BUILD_CONFIGURATION_TYPE_EXECUTABLE -D CRAFTER_BUILD_VERSION=\"$VERSION\" -c"
|
|
|
|
"$CXX" --target="$TARGET" -std=c++26 -stdlib=libc++ -O3 -march="$MARCH" -mtune="$MTUNE" -Wno-reserved-identifier -Wno-reserved-module-identifier --precompile "$STD_CPPM" -o ./build/std.pcm
|
|
|
|
# Asset partition: bootstrap compiles it WITHOUT CRAFTER_BUILD_HAS_ASSET so
|
|
# CompressAsset takes the stub branch and the impl unit doesn't try to
|
|
# `import Crafter.Asset` (no Crafter.Asset PCM exists at this stage — the
|
|
# self-host pass that follows wires in the real dep).
|
|
OBJECTS=""
|
|
for p in $PARTITIONS; do
|
|
"$CXX" $common_options -fmodule-output "interfaces/Crafter.Build-$p.cppm" -o "./build/Crafter.Build-$p.o"
|
|
OBJECTS="$OBJECTS ./build/Crafter.Build-$p.o"
|
|
done
|
|
"$CXX" $common_options -fmodule-output interfaces/Crafter.Build.cppm -o ./build/Crafter.Build.o
|
|
OBJECTS="$OBJECTS ./build/Crafter.Build.o"
|
|
|
|
for p in $PARTITIONS; do
|
|
"$CXX" $common_options "./implementations/Crafter.Build-$p.cpp" -o "./build/Crafter.Build-${p}_impl.o"
|
|
OBJECTS="$OBJECTS ./build/Crafter.Build-${p}_impl.o"
|
|
done
|
|
"$CXX" $common_options ./implementations/main.cpp -o ./build/main.o
|
|
|
|
# A fresh archive each time: `ar rcs` into an existing one keeps members a
|
|
# previous layout left behind.
|
|
rm -f ./lib/libcrafter-build.a
|
|
"$AR" rcs ./lib/libcrafter-build.a $OBJECTS
|
|
|
|
"$CXX" --target="$TARGET" -std=c++26 -stdlib=libc++ -O3 -march="$MARCH" -mtune="$MTUNE" -fuse-ld=lld \
|
|
-Wl,--export-dynamic $LIBCXX_LINK_FLAGS \
|
|
-L./build \
|
|
$OBJECTS \
|
|
./build/main.o \
|
|
-lSPIRV -lGenericCodeGen -lglslang -lOSDependent -lMachineIndependent -lglslang-default-resource-limits \
|
|
-ldl \
|
|
-o ./bin/crafter-build
|