477 lines
18 KiB
Markdown
477 lines
18 KiB
Markdown
# Installing llvm816
|
|
|
|
This document covers everything you need to get from a fresh Ubuntu /
|
|
Debian install to a working W65816 Clang compiler + Apple IIgs MAME
|
|
emulator + matching runtime libraries. The entire toolchain installs
|
|
*locally* under your repo checkout — nothing goes into `/usr/local`,
|
|
`/opt`, or your home directory beyond a few standard apt packages.
|
|
|
|
If you've never built LLVM or used a cross-compiler before, follow this
|
|
document top to bottom. If you're comfortable, the
|
|
[One-command install](#one-command-install) section gets you running
|
|
in 5-10 minutes.
|
|
|
|
---
|
|
|
|
## What you'll have when it's done
|
|
|
|
After install, the `llvm816/` directory tree contains everything:
|
|
|
|
| Component | Disk usage (approx) | Purpose |
|
|
|---|---:|---|
|
|
| `tools/llvm-mos/` | 5.0 GB | LLVM source tree (clone of llvm-mos). Our backend source is *symlinked* into here at build time. |
|
|
| `tools/llvm-mos-build/` | 1.4 GB | Compiled clang/llc/llvm-mc binaries. This is where you actually run the compiler from. |
|
|
| `tools/llvm-mos-sdk/` | 400 MB | Prebuilt llvm-mos SDK (the original 6502 distribution). Mostly unused by us; kept as a reference baseline. |
|
|
| `tools/calypsi/` | 580 MB | Commercial Calypsi 5.16 65816 C compiler — installed for output-quality comparisons in `compare/`. |
|
|
| `tools/orca-c/` | 10 MB | Apple's official ORCA/C compiler source — header reference for the IIgs Toolbox bindings. |
|
|
| `tools/gsos/` | 13 MB | Apple GS/OS 6.0.2 / 6.0.4 disk images for booting under MAME. |
|
|
| `tools/mame/roms/` | 1.5 MB | Apple IIgs ROM 01 + ROM 03 (downloaded from archive.org). |
|
|
| **Total** | **~7-8 GB** | |
|
|
|
|
Plus a few system-wide apt packages (cmake, ninja, MAME, ...). These
|
|
are listed up front in [System requirements](#system-requirements) so
|
|
you can audit them before installing.
|
|
|
|
The compiler binary itself is at
|
|
**`tools/llvm-mos-build/bin/clang`** — you'll see this path referenced
|
|
everywhere.
|
|
|
|
---
|
|
|
|
## System requirements
|
|
|
|
- **OS:** Ubuntu 22.04 LTS or 24.04 LTS (other Debian-based distros work
|
|
if you can find equivalents for the apt packages). Pure Arch / Fedora
|
|
installs need package-name translation but the project itself is
|
|
distro-neutral.
|
|
- **CPU:** any 64-bit x86 or ARM Linux machine. We're cross-compiling,
|
|
so the host CPU only matters for build speed.
|
|
- **Disk:** ~10 GB free total (~5 GB during build, ~7 GB after install
|
|
with all reference compilers). If you skip Calypsi (`--skip-calypsi`),
|
|
knock 580 MB off.
|
|
- **RAM:** 8 GB minimum for the default install (downloads a prebuilt
|
|
llvm-mos SDK). 16 GB recommended if you use `--build-llvm` (compiles
|
|
LLVM from source).
|
|
- **Time:** ~5 minutes for the default (prebuilt) path; 30-60 minutes
|
|
for `--build-llvm` on a modern laptop (depends on core count).
|
|
- **Network:** the install pulls ~500 MB of binaries from GitHub,
|
|
archive.org, and the Calypsi releases page. No proxy support
|
|
baked in — set `http_proxy` / `https_proxy` if you need one.
|
|
|
|
### apt packages installed
|
|
|
|
`scripts/installDeps.sh` runs `sudo apt-get install` for these
|
|
packages:
|
|
|
|
| Package | Why it's needed |
|
|
|---|---|
|
|
| `build-essential` | gcc, make, libc-dev — needed to build LLVM and our linker |
|
|
| `cmake`, `ninja-build` | LLVM's build system |
|
|
| `clang`, `lld` | Bootstrap a host clang (faster LLVM build than gcc) |
|
|
| `python3`, `python3-pip` | Build-time scripting + LLVM's lit test runner |
|
|
| `git` | Cloning the llvm-mos source tree |
|
|
| `zlib1g-dev`, `libedit-dev`, `libxml2-dev`, `libncurses-dev` | LLVM link-time deps |
|
|
| `zstd`, `xz-utils`, `unzip`, `tar` | Unpacking downloaded archives |
|
|
| `lua5.4`, `liblua5.4-dev` | MAME's autoboot scripting (used by the smoke harness) |
|
|
| `curl`, `ca-certificates` | Downloading installer payloads |
|
|
| `mame`, `mame-tools` | Apple IIgs emulator |
|
|
|
|
All packages are installed with `--no-install-recommends`, so the
|
|
total apt footprint is bounded. If you want to inspect or audit before
|
|
running, see `scripts/installDeps.sh` for the exact list.
|
|
|
|
> **Requires sudo:** the apt install step needs root. `setup.sh`
|
|
> prompts via `sudo` once and then continues without root for everything
|
|
> else.
|
|
|
|
---
|
|
|
|
## One-command install
|
|
|
|
```bash
|
|
git clone <this-repo-url> llvm816
|
|
cd llvm816
|
|
./setup.sh
|
|
```
|
|
|
|
That's it. `setup.sh` runs five stages in order:
|
|
|
|
| Stage | Script | What it does | Time |
|
|
|---|---|---|---|
|
|
| 1/5 | `installDeps.sh` | `sudo apt-get install` the packages listed above. | ~1 min |
|
|
| 2/5 | `installLlvmMos.sh` | Clone `llvm-mos` source (5 GB), download prebuilt llvm-mos SDK (400 MB), build our W65816 clang under `tools/llvm-mos-build/`. Without `--build-llvm`, downloads the prebuilt SDK only; clang for our target is then built incrementally. | ~5 min (no source build) or 30-60 min (with `--build-llvm`) |
|
|
| 3/5 | `installMame.sh` | Install MAME via apt, download `apple2gs.zip` (ROM 03) and `apple2gsr1.zip` (ROM 01) into `tools/mame/roms/`. | ~30 s |
|
|
| 4/5 | `installCalypsi.sh` | Download Calypsi 5.16 .deb, extract its payload into `tools/calypsi/` (no system-wide install). | ~30 s |
|
|
| 5/5 | `installOrcaC.sh` | Shallow clone of byteworksinc's ORCA/C repo into `tools/orca-c/` for toolbox header reference. | ~15 s |
|
|
|
|
After each stage, the script prints `=== N/5 stage-name ===` so you
|
|
can follow progress. At the end it runs `verify.sh` which sanity-
|
|
checks every tool was installed.
|
|
|
|
A successful install ends with:
|
|
|
|
```
|
|
[llvm816] setup complete
|
|
```
|
|
|
|
### `setup.sh` flags
|
|
|
|
| Flag | Effect |
|
|
|---|---|
|
|
| `--build-llvm` | Build clang from source (30-60 min) instead of using the prebuilt SDK. Required if you plan to modify the W65816 backend. |
|
|
| `--skip-deps` | Don't run apt (use if you've already installed the system packages). |
|
|
| `--skip-llvm` | Skip the LLVM clone + build. Useful for iterating on other parts. |
|
|
| `--skip-mame` | Skip MAME + ROM download. |
|
|
| `--skip-calypsi` | Skip Calypsi (saves 580 MB if you don't need the comparison benchmarks). |
|
|
| `--skip-orca` | Skip ORCA/C (saves ~10 MB; only needed if you regenerate `iigs/toolbox.h`). |
|
|
| `--skip-verify` | Don't run the post-install verification check. |
|
|
| `--verify-only` | Just run the verification check, don't install anything. |
|
|
|
|
---
|
|
|
|
## What gets installed where
|
|
|
|
After a complete `setup.sh` run, your `llvm816/` directory looks like
|
|
this:
|
|
|
|
```
|
|
llvm816/ ← your repo checkout
|
|
├── setup.sh ← the installer you just ran
|
|
├── README.md
|
|
├── docs/ ← documentation (you're reading INSTALL.md)
|
|
│ ├── INSTALL.md
|
|
│ ├── USAGE.md
|
|
│ └── multiSegmentPlan.md
|
|
├── src/ ← OUR backend source (W65816 target)
|
|
│ ├── llvm/lib/Target/W65816/ ← ~41 files; symlinked into tools/llvm-mos
|
|
│ ├── clang/ ← clang frontend hooks
|
|
│ └── link816/ ← linker source
|
|
├── patches/ ← upstream-llvm-mos patches
|
|
├── runtime/ ← C standard library + crt0
|
|
│ ├── include/ ← <stdio.h>, <stdlib.h>, <iigs/toolbox.h> ...
|
|
│ ├── src/ ← .c and .s sources
|
|
│ └── *.o ← built object files (after runtime/build.sh)
|
|
├── scripts/ ← install + run + bench scripts
|
|
├── benchmarks/ ← cycle-count benchmarks
|
|
├── compare/ ← side-by-side ours-vs-Calypsi assembly
|
|
├── demos/ ← example IIgs programs (helloBeep, reversi, ...)
|
|
├── tests/ ← larger compile-only tests (e.g. tests/lua/)
|
|
└── tools/ ← everything installed by setup.sh
|
|
├── llvm-mos/ (5.0 GB) — LLVM source tree clone
|
|
│ └── llvm/lib/Target/W65816/ ← symlinks point back to ../../src/llvm/lib/Target/W65816/
|
|
├── llvm-mos-build/ (1.4 GB) — cmake build directory
|
|
│ └── bin/
|
|
│ ├── clang → clang-23 ← THE COMPILER ⭐
|
|
│ ├── clang++ ← C++ driver
|
|
│ ├── clang-23 ← actual binary
|
|
│ ├── llc ← standalone codegen (.ll → .s)
|
|
│ ├── llvm-mc ← standalone assembler
|
|
│ ├── llvm-objdump ← disassembler
|
|
│ └── ... (FileCheck, llvm-readobj, opt, etc.)
|
|
├── llvm-mos-sdk/ (400 MB) — prebuilt llvm-mos SDK
|
|
├── link816 (~120 KB) — OUR LINKER ⭐
|
|
├── omfEmit (~70 KB) — OMF v2.1 emitter for GS/OS Loader
|
|
├── cadius/ — Apple ProDOS / GS/OS disk image tool
|
|
├── calypsi/ (580 MB) — Calypsi 5.16 reference compiler
|
|
├── orca-c/ (10 MB) — ORCA/C compiler (header reference)
|
|
├── gsos/ (13 MB) — GS/OS 6.0.2 / 6.0.4 disk images
|
|
├── mame/
|
|
│ └── roms/ (1.5 MB) — apple2gs ROM 01 + ROM 03
|
|
└── venv/ — Python venv (used by genToolbox.py)
|
|
```
|
|
|
|
The starred items (`clang` and `link816`) are the two binaries you
|
|
interact with daily. See [USAGE.md](USAGE.md) for how to use them.
|
|
|
|
### Why so much LLVM?
|
|
|
|
`tools/llvm-mos/` is a full LLVM source tree (about 5 GB). We need it
|
|
because our W65816 backend is part of LLVM — we build it as a
|
|
target inside LLVM's normal codegen pipeline. Our backend lives in
|
|
`src/llvm/lib/Target/W65816/`; `scripts/applyBackend.sh` symlinks it
|
|
into the LLVM source tree under `tools/llvm-mos/llvm/lib/Target/W65816/`
|
|
so cmake picks it up.
|
|
|
|
The size is unavoidable if you want to rebuild the backend. If you
|
|
don't plan to modify it, you could `rm -rf tools/llvm-mos` after a
|
|
successful build — but you'd have to re-clone to fix bugs.
|
|
|
|
### What's outside `tools/`?
|
|
|
|
Only the apt packages from [System requirements](#system-requirements).
|
|
`apt-get remove mame mame-tools` cleans those up if you want to fully
|
|
uninstall.
|
|
|
|
Importantly, the installer does **NOT** touch:
|
|
|
|
- `/usr/local/` (no `make install`)
|
|
- `/opt/` (no FHS-style component install)
|
|
- `~/.mame/` (we use `-rompath` to point at `tools/mame/roms/` instead)
|
|
- `~/.cache/` (downloads go to the repo-local `.cache/`)
|
|
|
|
To uninstall completely:
|
|
|
|
```bash
|
|
rm -rf llvm816/
|
|
sudo apt-get remove mame mame-tools build-essential cmake ninja-build \
|
|
clang lld lua5.4 liblua5.4-dev # if you want apt deps gone too
|
|
```
|
|
|
|
---
|
|
|
|
## Step-by-step (if `setup.sh` fails)
|
|
|
|
You can run each install script in isolation if a stage breaks. They're
|
|
idempotent — running them twice is a no-op (or a "fetch updates" for the
|
|
LLVM clone).
|
|
|
|
```bash
|
|
bash scripts/installDeps.sh # apt packages
|
|
bash scripts/installLlvmMos.sh # llvm-mos clone + prebuilt SDK
|
|
bash scripts/installLlvmMos.sh --build # also build clang/llc (slow)
|
|
bash scripts/installMame.sh # MAME + apple2gs ROMs
|
|
bash scripts/installCalypsi.sh # reference compiler (optional)
|
|
bash scripts/installOrcaC.sh # reference compiler (optional)
|
|
bash scripts/verify.sh # sanity-check everything
|
|
```
|
|
|
|
If you only want to *build* C programs (no benchmarks, no comparisons),
|
|
`installCalypsi.sh` and `installOrcaC.sh` are skippable.
|
|
|
|
### Building W65816 clang from source
|
|
|
|
The default install pulls a *prebuilt* llvm-mos SDK but builds our
|
|
W65816 backend incrementally on top. If you want to build everything
|
|
from source (recommended for backend development):
|
|
|
|
```bash
|
|
./setup.sh --build-llvm
|
|
```
|
|
|
|
This adds about 30-60 minutes to install time but means you can edit
|
|
files under `src/llvm/lib/Target/W65816/` and rebuild quickly.
|
|
|
|
After the initial source build, incremental rebuilds after editing
|
|
backend code take ~30 seconds:
|
|
|
|
```bash
|
|
ninja -C tools/llvm-mos-build llc clang
|
|
```
|
|
|
|
`scripts/applyBackend.sh` re-runs the symlink-into-LLVM step if you've
|
|
added new files under `src/llvm/lib/Target/W65816/`.
|
|
|
|
---
|
|
|
|
## Verifying the install
|
|
|
|
`setup.sh` automatically runs `scripts/verify.sh` at the end — it walks
|
|
every installed tool and checks each runs. If anything fails it shows
|
|
which step failed (e.g. `[FAIL] llvm-mos source tree` means the clone
|
|
didn't land where expected).
|
|
|
|
To re-verify later:
|
|
|
|
```bash
|
|
./setup.sh --verify-only
|
|
```
|
|
|
|
For a real end-to-end test (compiles and runs a tiny C program through
|
|
the entire pipeline):
|
|
|
|
```bash
|
|
# Build the runtime libraries (libc, libgcc, etc.) — ~30 s
|
|
bash runtime/build.sh
|
|
|
|
# Compile + disassemble a small C demo
|
|
bash scripts/cDemo.sh
|
|
|
|
# Run the full smoke test suite (~150 checks, takes ~3 min)
|
|
bash scripts/smokeTest.sh
|
|
```
|
|
|
|
A successful smoke test ends with:
|
|
|
|
```
|
|
[llvm816] all smoke checks passed
|
|
```
|
|
|
|
If smoke passes, your install is good.
|
|
|
|
---
|
|
|
|
## Updating
|
|
|
|
```bash
|
|
cd llvm816
|
|
git pull # update our backend source
|
|
bash scripts/applyBackend.sh # re-symlink into tools/llvm-mos
|
|
ninja -C tools/llvm-mos-build llc clang
|
|
bash runtime/build.sh
|
|
```
|
|
|
|
If you want a fully clean rebuild (e.g., to chase a "stale .o" bug):
|
|
|
|
```bash
|
|
rm -rf tools/llvm-mos-build
|
|
./setup.sh --build-llvm
|
|
```
|
|
|
|
---
|
|
|
|
## Uninstalling
|
|
|
|
The toolchain is fully contained under `llvm816/`:
|
|
|
|
```bash
|
|
rm -rf llvm816/
|
|
sudo apt-get remove mame mame-tools # if you want MAME gone too
|
|
# (also remove build-essential, cmake, etc., if they're not used elsewhere)
|
|
```
|
|
|
|
Nothing remains outside the repo.
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### `cmake: command not found` / `ninja: command not found`
|
|
|
|
The apt packages aren't installed yet:
|
|
|
|
```bash
|
|
bash scripts/installDeps.sh
|
|
```
|
|
|
|
### `clang: error: unable to find target 'w65816'`
|
|
|
|
You're invoking a clang that doesn't include our backend. Likely
|
|
causes:
|
|
|
|
1. You're using the **system** clang (`/usr/bin/clang`). The system
|
|
clang doesn't know W65816. Use the full path:
|
|
|
|
```bash
|
|
./tools/llvm-mos-build/bin/clang --target=w65816 ...
|
|
```
|
|
|
|
2. The build didn't complete. Check:
|
|
|
|
```bash
|
|
ls -la tools/llvm-mos-build/bin/clang # should be a symlink to clang-23
|
|
./tools/llvm-mos-build/bin/clang --print-targets | grep -i 65816
|
|
```
|
|
|
|
If the binary's missing or no W65816 target appears, rebuild:
|
|
|
|
```bash
|
|
bash scripts/applyBackend.sh
|
|
ninja -C tools/llvm-mos-build llc clang
|
|
```
|
|
|
|
3. You're using the prebuilt SDK (`tools/llvm-mos-sdk/bin/...`). That's
|
|
the original llvm-mos SDK; our W65816 target lives only in our
|
|
*source build* at `tools/llvm-mos-build/bin/`.
|
|
|
|
### `linkage error: missing __umulhisi3` / `missing __mulsi3` / similar
|
|
|
|
You forgot to link `runtime/libgcc.o`. See
|
|
[USAGE.md § Linking](USAGE.md#linking). Typical link line:
|
|
|
|
```bash
|
|
./tools/link816 -o myprog.bin --text-base 0x1000 \
|
|
runtime/crt0.o runtime/libc.o runtime/libgcc.o myprog.o
|
|
```
|
|
|
|
### `ROMs not found at runtime`
|
|
|
|
The apple2gs ROM download from archive.org occasionally fails. Re-run
|
|
the installer (it's idempotent and skips already-present ROMs):
|
|
|
|
```bash
|
|
bash scripts/installMame.sh
|
|
ls tools/mame/roms/ # should contain apple2gs.zip and apple2gsr1.zip
|
|
```
|
|
|
|
If you invoke `mame` directly without using our `runInMame.sh` wrapper,
|
|
pass `-rompath tools/mame/roms` so it finds them.
|
|
|
|
### MAME pops up a window I don't want
|
|
|
|
The supplied `scripts/runInMame.sh` runs headless (`-video none` plus
|
|
`SDL_VIDEODRIVER=dummy`). If you're calling `mame` yourself, add those
|
|
flags.
|
|
|
|
### `git: refusing to fetch into ...` for llvm-mos
|
|
|
|
`installLlvmMos.sh` refuses to refresh the LLVM clone if it has local
|
|
modifications or is on a non-`main` branch — because our backend
|
|
symlinks are stitched into the clone and a destructive refresh would
|
|
stomp them.
|
|
|
|
If you really want to refresh from upstream:
|
|
|
|
```bash
|
|
bash scripts/updateLlvmMos.sh
|
|
```
|
|
|
|
That script handles the symlinks safely.
|
|
|
|
### Disk fills up during `--build-llvm`
|
|
|
|
A full LLVM build needs ~12 GB of temporary build artifacts (cmake's
|
|
intermediate `.o` files, .a archives, etc.) on top of the 5 GB source
|
|
tree. Free ~15 GB before running `--build-llvm`.
|
|
|
|
Once the build completes, the *intermediate* artifacts under
|
|
`tools/llvm-mos-build/CMakeFiles/` can be deleted — the binaries
|
|
under `tools/llvm-mos-build/bin/` are self-contained:
|
|
|
|
```bash
|
|
rm -rf tools/llvm-mos-build/CMakeFiles tools/llvm-mos-build/lib
|
|
```
|
|
|
|
But this disables incremental rebuilds. Re-running `--build-llvm`
|
|
recreates everything.
|
|
|
|
### Calypsi install fails / I don't want it
|
|
|
|
Calypsi is only used by the `compare/` benchmarks for output-quality
|
|
comparison. Everything else works without it. Skip it:
|
|
|
|
```bash
|
|
./setup.sh --skip-calypsi
|
|
```
|
|
|
|
### MAME version mismatch warnings
|
|
|
|
We're tested against MAME 0.240 ROMs running on whatever MAME apt ships
|
|
with (typically 0.260+). Cross-version ROMs usually work but you may
|
|
see "BAD CHECKSUM" warnings. These are warnings, not errors — boot
|
|
proceeds normally.
|
|
|
|
If you want a clean match, the ROM 03 set from MAME 0.240 is
|
|
`apple2gs.zip` mirrored on archive.org; the installer pulls that exact
|
|
version.
|
|
|
|
### Smoke test fails on a single check
|
|
|
|
If `scripts/smokeTest.sh` fails one check but otherwise looks fine, it
|
|
might be MAME timing. Try:
|
|
|
|
```bash
|
|
MAME_CHECK_FRAME=600 MAME_SECS=12 bash scripts/smokeTest.sh
|
|
```
|
|
|
|
Some demos (especially the larger toolbox ones) need more wall-clock
|
|
time to fully draw. Persistent failures are real bugs — file an issue
|
|
with the failing check's output.
|
|
|
|
---
|
|
|
|
## Where to go next
|
|
|
|
- **Compile your first program:** [USAGE.md](USAGE.md).
|
|
- **Backend internals (if you're hacking on the compiler):**
|
|
[LLVM_65816_DESIGN.md](../LLVM_65816_DESIGN.md).
|
|
- **Feature matrix (what's implemented):** [STATUS.md](../STATUS.md).
|