#!/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"