Skip to content

Building from Source

DoubleGate edited this page Jul 8, 2026 · 1 revision

Building from Source

This guide covers building Rusty2600 across its supported targets.

Prerequisites

  1. Rust toolchain: Rusty2600 targets Rust 1.96 (Edition 2024), pinned in rust-toolchain.toml. Install via rustup and it will pick up the pin automatically.

  2. System dependencies (Linux): the desktop frontend needs wgpu/winit/cpal dependencies:

    # Debian/Ubuntu:
    sudo apt-get install -y --no-install-recommends \
      libasound2-dev libudev-dev \
      libxkbcommon-dev libwayland-dev \
      libx11-dev libxi-dev libxcursor-dev libxrandr-dev libxinerama-dev
    
    # Arch/CachyOS:
    sudo pacman -S --needed libxkbcommon wayland libx11 libxi libxcursor libxrandr libxinerama alsa-lib systemd-libs

Standard Desktop Build

# Build the whole workspace
cargo build --release --workspace

# Run the emulator
cargo run --release -p rusty2600-frontend -- path/to/rom.bin

Testing and Quality Gates

Rusty2600's CI mirrors this exactly (see .github/workflows/ci.yml):

# Unit + integration tests
cargo test --workspace

# The accuracy battery + golden-log/test-ROM suites
cargo test --workspace --features test-roms

# Formatting and linting — never add --all-features; per-feature jobs cover combinations instead
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings

# Doc build, warnings as errors
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps

no_std Gate

rusty2600-core (and everything it depends on) builds no_std + alloc for an embedded target — a CI gate proving the core stays portable, not a shipped product:

rustup target add thumbv7em-none-eabihf
cargo build -p rusty2600-core --target thumbv7em-none-eabihf --no-default-features

WebAssembly Build

rustup target add wasm32-unknown-unknown

The frontend has two mutually-exclusive wasm features — build exactly one at a time:

  • wasm-winit — the real native winit+wgpu+egui App compiled for wasm32-unknown-unknown, the same UI as desktop.
  • wasm-canvas — a simpler, still-fully-working canvas-2D requestAnimationFrame fallback, currently the deployed GitHub Pages build.
cargo build --target wasm32-unknown-unknown --no-default-features --features wasm-winit -p rusty2600-frontend

debug-hooks is wasm-safe alongside wasm-winit (--features wasm-winit,debug-hooks), exposing the core debugger panels in-browser. See Frontend-Architecture for the full feature-flag list and current wasm status.

Optional Native Features

Every optional feature is off by default and additive — a default build stays byte-identical whether or not any of these existed. Enable what you need:

cargo build --release -p rusty2600-frontend --features scripting,netplay,hd-pack,retroachievements,debug-hooks
Feature Adds
debug-hooks The live debugger overlay (default-on for native)
scripting Lua scripting via mlua (native-only; see Scripting-Engine)
netplay 2-player rollback netplay via ggrs (see Netplay-and-Rollback)
hd-pack TIA object-ID mask + HD replacement-art live rendering splice
retroachievements rcheevos-backed achievement tracking and hardcore mode
emu-thread Runs the emulator core on a dedicated thread (native-only)
help-tui A ratatui terminal help browser (native-only)

Mobile Builds

Android needs Android Studio + the JNI host in android/; iOS needs Xcode + ios/. Both are bridged via rusty2600-mobile using UniFFI — see Mobile-and-Cross-Platform.

# Cross-compile the shared library for Android
rustup target add aarch64-linux-android x86_64-linux-android
cargo install cargo-ndk
android/regenerate-bindings.sh

A key property of the UniFFI bridge: uniffi-bindgen generate only introspects the compiled library's embedded metadata, which is identical regardless of which platform compiled it — so the Swift bindings checked into ios/RustyMobileFFI/ were genuinely generated on Linux, even though the actual aarch64-apple-ios cross-compilation still needs a real Mac to run.

Clone this wiki locally