1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# Tribal knowledge: build system
## At a glance
- **Key files:** `build.zig` (desktop orchestrator), `build_config.rb` (mruby + the
4 mrbgems), `rebuild.sh` (incremental), `build_web.sh` (web), each `mrbgems/*/mrbgem.rake`.
- **Commands:** `zig build` / `zig build run`; `./rebuild.sh`;
`EMSDK_ENV=~/emsdk/emsdk_env.sh ./build_web.sh`; run `./zig-out/bin/game path.rb`.
- **Cross-refs:** rules `link-order`, `mruby-rebuild`, `lld-no-gcc-lto`,
`raylib-platform-objs`, `wsl-toolchain`; design `docs/BUILD_SYSTEM.md`; human steps
`BUILDING.md`; skill `build-and-verify`.
## Topology
`Ruby game code → mruby VM → Rl::/Rml::/Flecs:: bindings → raylib/RmlUi/flecs`,
linked by **Zig** (desktop) or **emscripten** (web). `src/main.c` boots mruby and
runs a script (`argv[1]`, default `game/main.rb`).
Four native libs are built separately and linked at the end:
- `build/desktop/libraylib.a` — raylib via `make` (guarded; built once).
- `vendor/rmlui/build-static/librmlui.a` — RmlUi via `cmake`, target `rmlui_core` ONLY.
- `build/desktop/libflecs.a` — flecs amalgamation, one `cc` object.
- `vendor/mruby/build/host/lib/libmruby.a` — mruby + our 3 mrbgems via `rake`
(rebuilt every `zig build`; rake is incremental).
## Commands
- Desktop: `zig build` / `zig build run` (orchestrates all of the above).
- Incremental binding work: `./rebuild.sh` (rake libmruby + zig link).
- Web: `EMSDK_ENV=~/emsdk/emsdk_env.sh ./build_web.sh` → `build/web/game.{html,js,wasm,data}`.
- Always export the cleaned PATH first (see rules/wsl-toolchain.md).
## Why zig links GNU libstdc++ directly (build.zig)
zig 0.16's `linkSystemLibrary("stdc++")` hijacks to its own LLVM **libc++**, which
lacks the GNU libstdc++ ABI symbols RmlUi needs. So we `addObjectFile`
`/usr/lib/libstdc++.so` and `/usr/lib/libgcc_s.so.1` (the latter for
`_Unwind_Resume`: mruby is built with `MRB_USE_CXX_EXCEPTION` because a C++
mrbgem, rmlui, is present).
## mruby config (build_config.rb)
- `conf.disable_presym` — lets us add new binding method names without
regenerating the presym table (avoids stale-symbol errors on rebuild).
- One `MRuby::Build` (host) + one `MRuby::CrossBuild('web')` guarded by
`JAMSTACK_WEB`. Both list the same 3 gems (raylib, rmlui, flecs).
- `JAMSTACK_ROOT` is exported by the build scripts so mrbgem.rake/build_config
resolve paths.
## Per-target raylib objects
raylib shares `.o` in `vendor/raylib/src` across platforms → see
rules/raylib-platform-objs.md. Output dirs are `build/desktop` and `build/web`.
## Gotcha index (when something breaks)
- "multiple definition" at link → stale mruby objects: `rm -rf vendor/mruby/build`.
- "undefined reference" to ecs_/Rml/raylib syms → link order or a missing native lib.
- rake tries to build `mruby`/`mirb` and fails → you ran plain `rake`; target the
`libmruby.a` path instead.
- raylib symbols are wasm/desktop-mismatched → forgot `make clean` between targets.
|