Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# RustyNES libretro core — buildbot recipe.
#
# Populates RetroArch's built-in core downloader via the shared libretro CI
# templates (git.libretro.com/libretro-infrastructure/ci-templates). Added
# per https://github.com/doublegate/RustyNES/issues/311.
#
# `CORENAME` is `rustynes`, NOT `rustynes_libretro` or `rustynes-libretro`:
# these templates always run a fixed `mv lib${CORENAME}.<ext>
# ${CORENAME}_libretro.<ext>` step. `crates/rustynes-libretro/Cargo.toml`
# sets `[lib] name = "rustynes"` explicitly (its `[package] name` stays
# `rustynes-libretro` for `-p rustynes-libretro` scoping everywhere else),
# so `CORENAME=rustynes` makes both the compiled-artifact name and the
# final packaged name resolve correctly to `rustynes_libretro.<ext>` —
# matching the already-published `rustynes_libretro.info`.
#
# `cargo build --release --target <triple>` here runs from the repo root
# with no `-p` flag (the template scripts are centrally maintained and not
# per-core editable); the root `Cargo.toml`'s `[workspace] default-members =
# ["crates/rustynes-libretro"]` is what scopes that bare command to just
# this crate instead of all 18 workspace members.
#
# Platform scope: mirrors the two proven, currently-building reference
# cores (doukutsu-rs-libretro, holani-retro) minus platforms we have
# concrete evidence won't build — no `rust-libnx*.yml` template exists in
# ci-templates (Nintendo Switch is not buildable this way for a Rust core
# today), and no reference core includes webOS. Both can be added later
# once the basics are proven on the buildbot.

.core-defs:
variables:
CORENAME: rustynes

include:
################################## DESKTOPS ################################
# Windows 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/rust-windows-x64.yml'

# Linux 64-bit
- project: 'libretro-infrastructure/ci-templates'
file: '/rust-linux-x64.yml'

# macOS/iOS/tvOS
- project: 'libretro-infrastructure/ci-templates'
file: '/rust-apple.yml'

################################## CELLULAR ################################
# Android
- project: 'libretro-infrastructure/ci-templates'
file: '/rust-android-jni.yml'

stages:
- build-prepare
- build-shared
- build-static

################################### DESKTOPS #################################
# Windows 64-bit
libretro-build-windows-x64:
extends:
- .libretro-rust-windows-x64-default
- .core-defs

# Linux 64-bit
libretro-build-linux-x64:
extends:
- .libretro-rust-linux-x64-default
- .core-defs

# macOS 64-bit
libretro-build-osx-x64:
extends:
- .libretro-rust-osx-x86_64-default
- .core-defs

# macOS ARM 64-bit
libretro-build-osx-arm64:
extends:
- .libretro-rust-osx-arm64-default
- .core-defs

################################### CELLULAR #################################
# Android ARMv7a
android-armeabi-v7a:
extends:
- .libretro-rust-android-jni-armeabi-v7a
- .core-defs

# Android ARMv8a
android-arm64-v8a:
extends:
- .libretro-rust-android-jni-arm64-v8a
- .core-defs

# Android 64-bit x86
android-x86_64:
extends:
- .libretro-rust-android-jni-x86_64
- .core-defs

# Android 32-bit x86
android-x86:
extends:
- .libretro-rust-android-jni-x86
- .core-defs

# iOS
libretro-build-ios-arm64:
extends:
- .libretro-rust-ios-arm64-default
- .core-defs

# tvOS
libretro-build-tvos-arm64:
extends:
- .libretro-rust-tvos-arm64-default
- .core-defs
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@ cycle-accurate core later replaced.

## [Unreleased]

### Added

- Libretro buildbot CI recipe (`.gitlab-ci.yml`, issue #311) covering Windows
x64, Linux x64, macOS x64/arm64, Android (4 ABIs), iOS arm64, and tvOS
arm64 — the missing piece to get RustyNES onto RetroArch's built-in core
downloader (the repo was already integrated with the legacy
`libretro-super` scripts). Paired with a `[workspace] default-members`
fix so the templates' unscoped `cargo build --release --target <triple>`
builds only `crates/rustynes-libretro`, and a `[lib] name = "rustynes"`
override resolving a compiled-artifact naming collision with the shared
CI templates' fixed `${CORENAME}_libretro` convention.
- Libretro core feature completion: native `RETRO_ENVIRONMENT_SET_MEMORY_MAPS`
registration (the memory-descriptor path RetroAchievements' `rcheevos`
prefers, alongside the existing legacy pointer API); an FDS load-path fix
(`.fds` content is now correctly routed to `Nes::from_disk` with a
`disksys.rom` lookup in the frontend's system directory — previously
broken despite `valid_extensions` advertising it) plus a full disk-control
interface for FDS multi-side swapping via RetroArch's Quick Menu; native
Game Genie cheat support (`on_cheat_set`/`on_cheat_reset`); and a
`get_fastforwarding`-gated audio-push skip during RetroArch's
fast-forward/rollback-netplay catch-up path.

## [2.2.1] - 2026-07-15 - Housekeeping patch (dev-tooling archival + dependency consolidation + FDS test corpus)

Zero accuracy, feature, or core changes — the deterministic `#![no_std]` chip
Expand Down
11 changes: 11 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ members = [
"crates/rustynes-ra",
"crates/rustynes-monetization", "crates/rustynes-libretro",
]
# The libretro buildbot's shared CI templates run a bare, unscoped
# `cargo build --release --target <triple>` from the repo root (no `-p`,
# no `--manifest-path` — the script is centrally maintained and can't be
# edited per-core). Scoping the default member to just the libretro crate
# keeps that command building ONLY `rustynes-libretro`, not all 18 workspace
# members (in particular `rustynes-frontend`, which needs wgpu/winit/cpal/
# wayland system libs the buildbot's headless cross-compile image doesn't
# have). This does not change any `--workspace`/`-p <crate>`-scoped command
# — every CI workflow, this crate's own Makefile, and every scripts/*.sh
# invocation already scopes explicitly. See `.gitlab-ci.yml`.
default-members = ["crates/rustynes-libretro"]

[workspace.package]
version = "2.2.1"
Expand Down
10 changes: 5 additions & 5 deletions SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Thank you for using RustyNES! This document provides guidance on how to get help

```bash
git pull origin main
cargo build --release
cargo build --release --workspace
```

---
Expand Down Expand Up @@ -135,20 +135,20 @@ A: See [docs/dev/BUILD.md](docs/dev/BUILD.md) for detailed build instructions. Q
```bash
git clone https://github.com/doublegate/RustyNES.git
cd RustyNES
cargo build --release
cargo build --release --workspace
```

**Q: What are the prerequisites?**

A: Rust 1.86 (pinned in `rust-toolchain.toml`; `rustup` auto-installs it) and the `winit` + `wgpu` + `cpal` system libraries (libxkbcommon / wayland / alsa / udev on Linux; nothing extra on macOS/Windows). See [docs/dev/BUILD.md](docs/dev/BUILD.md) for platform-specific instructions.
A: Rust 1.96 (pinned in `rust-toolchain.toml`; `rustup` auto-installs it) and the `winit` + `wgpu` + `cpal` system libraries (libxkbcommon / wayland / alsa / udev on Linux; nothing extra on macOS/Windows). See [docs/dev/BUILD.md](docs/dev/BUILD.md) for platform-specific instructions.

**Q: Build is failing, what do I do?**

A:

1. Ensure you have Rust 1.86 or newer: `rustc --version`
1. Ensure you have Rust 1.96 or newer: `rustc --version`
2. Install the frontend system libraries (see [BUILD.md](docs/dev/BUILD.md))
3. Try a clean build: `cargo clean && cargo build`
3. Try a clean build: `cargo clean && cargo build --workspace`
4. Check [GitHub Issues](https://github.com/doublegate/RustyNES/issues) for known build problems
5. Ask for help in [Discussions](https://github.com/doublegate/RustyNES/discussions)

Expand Down
17 changes: 16 additions & 1 deletion crates/rustynes-libretro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,29 @@ keywords = ["nes", "emulator", "famicom", "libretro", "retroarch"]
categories = ["emulators"]

[lib]
# Explicit override so the compiled artifact is `librustynes.{so,dylib,a}` /
# `rustynes.dll` rather than the package-name default `rustynes_libretro`.
# The libretro buildbot's shared CI templates (`libretro-infrastructure/
# ci-templates`) run a fixed `mv lib${CORENAME}.so ${CORENAME}_libretro.so`
# step, so the compiled lib name must NOT already contain `_libretro` or the
# final artifact name would double up (`rustynes_libretro_libretro.so`).
# `CORENAME=rustynes` in `.gitlab-ci.yml` pairs with this to produce the
# correct `rustynes_libretro.*` name both CI paths (this and the legacy
# libretro-super Makefile) ultimately require. See `.gitlab-ci.yml` and
# `Makefile` in this crate.
name = "rustynes"
crate-type = ["cdylib", "staticlib"]

[lints]
workspace = true

[dependencies]
libc = "0.2.186"
rust-libretro = "0.3.2"
# `unstable-env-commands` unlocks `set_memory_maps` (RetroAchievements'
# preferred memory-descriptor path) and `get_fastforwarding` (used to skip
# non-essential audio work during RetroArch's rollback-netplay/fast-forward
# fast path) — both are compiled out of `rust-libretro` without this feature.
rust-libretro = { version = "0.3.2", features = ["unstable-env-commands"] }

[dependencies.rustynes-core]
path = "../rustynes-core"
Expand Down
15 changes: 13 additions & 2 deletions crates/rustynes-libretro/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ ifeq ($(platform),android)
else ifeq ($(ARCH),x86)
RUST_TARGET := i686-linux-android
endif
else ifeq ($(platform),osx)
# Only force an explicit cross-target when the buildbot tells us the arch
# (ARCH set); a bare local `make` on macOS with no ARCH falls through to
# native compile (empty RUST_TARGET), same as before this branch existed.
ifeq ($(ARCH),arm64)
RUST_TARGET := aarch64-apple-darwin
else ifeq ($(ARCH),aarch64)
RUST_TARGET := aarch64-apple-darwin
else ifeq ($(ARCH),x86_64)
RUST_TARGET := x86_64-apple-darwin
endif
else ifeq ($(platform),ios)
RUST_TARGET := aarch64-apple-ios
else ifeq ($(platform),tvos)
Expand Down Expand Up @@ -94,12 +105,12 @@ all: release

build:
$(CARGO_CMD)
cp $(OUT_DIR)/debug/$(PREFIX)rustynes_libretro.$(EXT) rustynes_libretro.$(EXT)
cp $(OUT_DIR)/debug/$(PREFIX)rustynes.$(EXT) rustynes_libretro.$(EXT)
@echo "Copied debug core to rustynes_libretro.$(EXT)"

release:
$(CARGO_CMD) --release
cp $(OUT_DIR)/release/$(PREFIX)rustynes_libretro.$(EXT) rustynes_libretro.$(EXT)
cp $(OUT_DIR)/release/$(PREFIX)rustynes.$(EXT) rustynes_libretro.$(EXT)
@echo "Copied release core to rustynes_libretro.$(EXT)"

clean:
Expand Down
Loading