jevsnes.git / third-party / rust / README.md
1# Chapter 19: rust, how crates reach the build
2
3In an ordinary Rust project, `cargo` reads `Cargo.toml`, downloads the
4crates and builds everything. Here buck2 builds everything (the C bot
5included), and buck2 does not read `Cargo.toml`. Something has to translate.
6That something is [reindeer](https://github.com/facebookincubator/reindeer).
7
8```mermaid
9flowchart LR
10  toml["Cargo.toml (hand-written)"] --> lock["Cargo.lock (resolved)"]
11  lock --> reindeer["reindeer buckify"]
12  fix["fixups/ and reindeer.toml"] --> reindeer
13  reindeer --> buck["BUCK (generated): one target per crate"]
14  buck --> code["first-party code: //third-party/rust:<crate>"]
15```
16
17`Cargo.toml` here is not a real package anybody builds with cargo. It is a
18list of every third-party crate the project uses, with versions and
19features, and a comment on most of them saying why. reindeer resolves it,
20and writes `BUCK`: about four hundred `http_archive` downloads (crates are
21fetched at build time, pinned by `Cargo.lock`, not vendored into git) and a
22`rust_library` for each. First-party code then depends on, say,
23`//third-party/rust:egui`.
24
25Three crates are not from crates.io at all:
26
27- **jgenesis** (`jgenesis/`), the emulator, as a git subtree of
28  [jsgroth/jgenesis](https://github.com/jsgroth/jgenesis) (GPL-3.0) from
29  upstream `d19ee94f`. This project uses its `snes-core`, `snes-config` and
30  `jgenesis-common` crates as path dependencies. It carries two commits of
31  ours: "jgenesis: expose work RAM from snes-core" (`SnesEmulator::wram()`)
32  and "jgenesis: let a host write work RAM" (`wram_mut()`, for the bot's
33  cheats).
34- **jevcrates** (`jevcrates/`), a git submodule: `jev-protocol`,
35  `jev-client` and `jev-http`, the code every Jev project here shares. It
36  came out of this repository (as `packages/jev` and `packages/jev-http`)
37  on 2026-10-01. Its URL in `.gitmodules` is relative (`../jevcrates.git`),
38  so it resolves beside wherever this repository was cloned from, which is
39  why `git clone --recurse-submodules` from the lmjtfy site works.
40- **rustls-rustcrypto**, from its git repository's `master` branch.
41
42> **Aside: why so much effort to avoid C?** `jev-http` speaks HTTP/2 over
43> rustls with the pure-Rust RustCrypto provider, and replay keyframes are
44> compressed with `ruzstd`, a pure-Rust zstd. Every C dependency is a build
45> script finding a system library, and every one of those is a way for a
46> build to fail on a machine that is not this one. `alsa-sys` (sound) is
47> the one crate that links a system library at build time; the window's
48> wayland, xkbcommon, X11, Vulkan and GL are opened at startup instead.
49
50> **Try it.** After changing `Cargo.toml`:
51>
52>     nix develop -c sh -c 'cd third-party/rust && reindeer --third-party-dir . buckify'
53>
54> then `git diff --stat third-party/rust/BUCK` to see what moved.
55
56## For the people who maintain it
57
58### In this folder
59
60| Path | What |
61| --- | --- |
62| [fixups/](fixups/) | Chapter 20: per-crate answers reindeer cannot infer, chiefly whether a crate's `build.rs` must run. |
63| [top/](top/) | Chapter 21: the empty crate root the manifest needs in order to be a package. |
64| [Cargo.toml](Cargo.toml) | The dependency list. The only file here edited by hand to add or bump a crate. |
65| [Cargo.lock](Cargo.lock) | The resolution. Committed. |
66| [BUCK](BUCK) | GENERATED by reindeer. Never edited by hand. |
67| [reindeer.toml](reindeer.toml) | Reindeer's settings: `cargo_env = true`, so every crate gets the `CARGO_PKG_*` variables cargo would set. |
68| [README.md](README.md) | This chapter. |
69| [CLAUDE.md](CLAUDE.md) | What breaks the generated graph, for agents. |
70| [jgenesis/](jgenesis/) | The emulator, a git subtree. No chapter: upstream's own docs describe it, and a subtree pull would be the only thing keeping ours honest. |
71| [jevcrates](jevcrates) | The Jev crates, a git submodule with a guide of its own. No chapter here. |
72
73← Previous: [Chapter 18, patches/](../c/patches/) · Up: [third-party](../) · Next: [Chapter 20, fixups/](fixups/) →