65816-llvm-mos/scripts/installLlvmMos.sh
2026-09-27 21:22:25 -05:00

104 lines
4.4 KiB
Bash
Executable file

#!/usr/bin/env bash
# Install + build the W65816 toolchain on top of llvm-mos:
# 1. Clone llvm-mos source at the commit pinned in llvmMosCommit.txt.
# 2. Apply our W65816 backend INTO the clone (symlinks + patches).
# 3. Configure + build clang + llc + llvm-mc + llvm-ar with the W65816 target.
# 4. Build link816 + omfEmit (the linker).
# 5. Build the runtime (libc.o, crt0.o, libgcc.o, etc.).
#
# Flags:
# --build (no-op; retained for backward compat — we always build)
set -euo pipefail
source "$(dirname "$0")/common.sh"
for arg in "$@"; do
case "$arg" in
--build) ;; # no-op; we always build now (see step 3)
*) die "unknown flag: $arg" ;;
esac
done
# 1. Source tree for backend development, at the pinned commit.
#
# IMPORTANT: this clone is ephemeral scaffolding, not where we do work. Our
# own sources live in $PROJECT_ROOT/src/ and $PROJECT_ROOT/patches/ and are
# stitched into this tree by applyBackend.sh. Moving the clone therefore
# unapplies the backend first; a clone with any OTHER local change, or on a
# branch other than main, is left for a human to sort out.
pinnedCommit="$(llvmMosPinnedCommit)"
if [ -d "$LLVM_SRC/.git" ]; then
currentCommit="$(git -C "$LLVM_SRC" rev-parse HEAD)"
if [ "$currentCommit" = "$pinnedCommit" ]; then
log "llvm-mos source already at pinned commit ${pinnedCommit:0:12}"
else
currentBranch="$(git -C "$LLVM_SRC" rev-parse --abbrev-ref HEAD)"
if [ "$currentBranch" != "main" ]; then
die "llvm-mos clone is on branch '$currentBranch', not main; refusing to move it to the pinned commit ${pinnedCommit:0:12}"
fi
log "llvm-mos source at ${currentCommit:0:12}; moving to pinned ${pinnedCommit:0:12}"
unapplyBackend
checkoutLlvmMosCommit "$pinnedCommit"
fi
else
log "cloning llvm-mos at pinned commit ${pinnedCommit:0:12} (shallow)"
git init -q "$LLVM_SRC"
git -C "$LLVM_SRC" remote add origin "$LLVM_MOS_URL"
checkoutLlvmMosCommit "$pinnedCommit"
fi
# 2. Apply our W65816 backend INTO the clone (symlinks + patches).
# Must run BEFORE cmake configure so the W65816 target dir + cmake
# patch are present.
log "applying W65816 backend (symlinks + patches)"
bash "$(dirname "$0")/applyBackend.sh"
# 3. Configure (first time only) + build LLVM with W65816 enabled. ninja
# runs every time: it is a few-second no-op when nothing changed, and it
# is what picks up a moved pin or an edited backend source.
needCmd cmake
needCmd ninja
if [ -f "$LLVM_BUILD/build.ninja" ]; then
log "llvm-mos build already configured"
else
log "configuring llvm-mos build (LLVM + clang + lld)"
install -d "$LLVM_BUILD"
cmake -S "$LLVM_SRC/llvm" -B "$LLVM_BUILD" -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_TARGETS_TO_BUILD="" \
-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="MOS;W65816" \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_PARALLEL_LINK_JOBS=1 \
-DLLVM_USE_LINKER=lld \
-DLLVM_INCLUDE_TESTS=OFF \
-DLLVM_INCLUDE_EXAMPLES=OFF \
-DLLVM_INCLUDE_BENCHMARKS=OFF
fi
# LTO chain: llvm-link merges bitcode, opt runs IR-level optimizations
# (including the Layer 2 gate from Phase 1.12), llvm-as / llvm-dis are the
# .bc <-> .ll round-trip for debugging. Phase 5.2. llvm-ar archives the
# objects of client libraries (joeylib's libjoey.a).
log "building clang, llc, llvm-mc, llvm-ar, llvm-objdump + LTO tools (first build ~30-60 min)"
ninja -C "$LLVM_BUILD" clang llc llvm-mc llvm-ar llvm-objdump llvm-readobj \
llvm-link llvm-as llvm-dis opt
log "llvm build done: $LLVM_BUILD/bin/clang"
# Sanity check: llc must list w65816 as a registered target.
if ! "$LLVM_BUILD/bin/llc" --version 2>/dev/null | grep -q "^[[:space:]]*w65816[[:space:]]"; then
"$LLVM_BUILD/bin/llc" --version 2>/dev/null | head -20
warn "llc built but does NOT list w65816 as a target. Backend symlinks/patches may have failed. Re-run scripts/applyBackend.sh and ninja -C tools/llvm-mos-build."
fi
# 4. Build link816 + omfEmit.
log "building link816 + omfEmit"
make -C "$PROJECT_ROOT/src/link816" all
# 5. Build the runtime (libc.o, crt0.o, libgcc.o, etc.).
log "building runtime"
bash "$PROJECT_ROOT/runtime/build.sh"
log "llvm-mos install done"
log " source: $LLVM_SRC (llvm-mos ${pinnedCommit:0:12})"
log " build: $LLVM_BUILD"
log " clang: $LLVM_BUILD/bin/clang"
log " link816: $PROJECT_ROOT/tools/link816"
log " omfEmit: $PROJECT_ROOT/tools/omfEmit"