build: standardize build dir policy

This commit is contained in:
scawful
2025-12-22 14:28:55 -05:00
parent 9333498538
commit ea4e1873de
8 changed files with 268 additions and 194 deletions

View File

@@ -60,26 +60,26 @@ All bundled third-party code (SDL, ImGui, ImGui Test Engine, Asar, nlohmann/json
- **`./build/bin/yaze`** full GUI editor with multi-session dockspace, theming, and ROM patching. - **`./build/bin/yaze`** full GUI editor with multi-session dockspace, theming, and ROM patching.
- **Web App (Preview)** browser-based editor at your deployed instance; see [`docs/public/usage/web-app.md`](docs/public/usage/web-app.md) for details and limitations. - **Web App (Preview)** browser-based editor at your deployed instance; see [`docs/public/usage/web-app.md`](docs/public/usage/web-app.md) for details and limitations.
- **`./build/bin/z3ed --tui`** CLI/TUI companion for scripting, AI-assisted edits, and Asar workflows. - **`./build/bin/z3ed --tui`** CLI/TUI companion for scripting, AI-assisted edits, and Asar workflows.
- **`./build_ai/bin/yaze_test --unit|--integration|--e2e`** structured test runner for quick regression checks. - **`ctest --test-dir build -L unit|integration|e2e`** structured test runner for quick regression checks.
- **`z3ed` + macOS automation** pair the CLI with sketchybar/yabai/skhd or Emacs/Spacemacs to drive ROM workflows without opening the GUI. - **`z3ed` + macOS automation** pair the CLI with sketchybar/yabai/skhd or Emacs/Spacemacs to drive ROM workflows without opening the GUI.
Typical commands: Typical commands:
```bash ```bash
# Launch GUI with a ROM # Launch GUI with a ROM
./build/bin/yaze zelda3.sfc ./build/bin/yaze roms/alttp_vanilla.sfc
# Apply a patch via CLI # Apply a patch via CLI
./build/bin/z3ed asar patch.asm --rom zelda3.sfc ./build/bin/z3ed asar patch.asm --rom roms/alttp_vanilla.sfc
# Run focused tests # Run focused tests
cmake --build --preset mac-ai --target yaze_test cmake --build --preset mac-ai --target yaze_test
./build_ai/bin/yaze_test --unit ctest --test-dir build -L unit
``` ```
## Testing ## Testing
- `./build_ai/bin/yaze_test --unit` for fast checks; add `--integration` or `--e2e --show-gui` for broader coverage. - `ctest --test-dir build -L unit` for fast checks; add `-L integration` or `-L e2e --output-on-failure` for broader coverage.
- `ctest --preset dev` mirrors CIs stable set; `ctest --preset all` runs the full matrix. - `ctest --preset dev` mirrors CIs stable set; `ctest --preset all` runs the full matrix.
- Set `YAZE_TEST_ROM_PATH` or pass `--rom-path` when a test needs a real ROM image. - Set `YAZE_TEST_ROM_VANILLA` or pass `--rom-vanilla` when a test needs a real ROM image (legacy `--rom-path` still works).
## Documentation ## Documentation
- Human-readable docs live under `docs/public/` with an entry point at [`docs/public/index.md`](docs/public/index.md). - Human-readable docs live under `docs/public/` with an entry point at [`docs/public/index.md`](docs/public/index.md).

View File

@@ -42,8 +42,10 @@ Select a preset that matches your platform and workflow:
|----------|---------| |----------|---------|
| Debug builds | `mac-dbg`, `lin-dbg`, `win-dbg` | | Debug builds | `mac-dbg`, `lin-dbg`, `win-dbg` |
| AI-enabled builds | `mac-ai`, `lin-ai`, `win-ai` | | AI-enabled builds | `mac-ai`, `lin-ai`, `win-ai` |
| AI + system gRPC (macOS) | `mac-ai-fast` |
| Release builds | `mac-rel`, `lin-rel`, `win-rel` | | Release builds | `mac-rel`, `lin-rel`, `win-rel` |
| Development (ROM tests) | `mac-dev`, `lin-dev`, `win-dev` | | Development (ROM tests) | `mac-dev`, `lin-dev`, `win-dev` |
| Fast test builds | `mac-test`, `lin-test`, `win-test` |
**Build Commands:** **Build Commands:**
```bash ```bash
@@ -57,6 +59,20 @@ See the [CMake Presets Guide](presets.md) for the complete preset reference.
--- ---
## Build Directory Policy
By default, native builds live in `build/` and WASM builds live in `build-wasm/`. Keep additional build directories outside the repo to avoid size creep:
```bash
cp CMakeUserPresets.json.example CMakeUserPresets.json
export YAZE_BUILD_ROOT="$HOME/.cache/yaze"
cmake --preset dev-local
```
For scripts and agent-driven builds, set `YAZE_BUILD_DIR` to an external path (for example, `$HOME/.cache/yaze/build`).
---
## Feature Toggles ## Feature Toggles
### Windows Presets ### Windows Presets
@@ -117,6 +133,21 @@ brew install yaml-cpp googletest
> **Note:** In sandboxed environments, install yaml-cpp and googletest via Homebrew to avoid network fetch failures. The build system auto-detects Homebrew installations at `/opt/homebrew/opt/` (Apple Silicon) or `/usr/local/opt/` (Intel). > **Note:** In sandboxed environments, install yaml-cpp and googletest via Homebrew to avoid network fetch failures. The build system auto-detects Homebrew installations at `/opt/homebrew/opt/` (Apple Silicon) or `/usr/local/opt/` (Intel).
#### Toolchain Options (macOS)
AppleClang (`/usr/bin/clang`) is the default and most reliable. If you want Homebrew LLVM, use the provided toolchain file so libc++ headers and rpaths are consistent:
```bash
# AppleClang (recommended)
cmake --preset mac-dbg --fresh -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++
# Homebrew LLVM
brew install llvm
cmake --preset mac-dbg --fresh -DCMAKE_TOOLCHAIN_FILE=cmake/llvm-brew.toolchain.cmake
```
`mac-ai-fast` expects Homebrew gRPC/protobuf/abseil (`brew install grpc protobuf abseil`).
### Linux (Ubuntu/Debian) ### Linux (Ubuntu/Debian)
```bash ```bash
@@ -152,13 +183,13 @@ The easiest way to run tests is with `ctest` presets.
```bash ```bash
# Configure a development build (enables ROM-dependent tests) # Configure a development build (enables ROM-dependent tests)
cmake --preset mac-dev -DYAZE_TEST_ROM_PATH=/path/to/your/zelda3.sfc cmake --preset mac-dev -DYAZE_TEST_ROM_VANILLA_PATH="$PWD/roms/alttp_vanilla.sfc"
# Build the tests # Build the tests
cmake --build --preset mac-dev --target yaze_test cmake --build --preset mac-dev --target yaze_test
# Run stable tests (fast, run in CI) # Run stable tests (fast, run in CI)
ctest --preset dev ctest --preset stable
# Run all tests, including ROM-dependent and experimental # Run all tests, including ROM-dependent and experimental
ctest --preset all ctest --preset all
@@ -169,8 +200,11 @@ ctest --preset all
You can also run tests by invoking the test executable directly or using CTest with labels. You can also run tests by invoking the test executable directly or using CTest with labels.
```bash ```bash
# Run all tests via the executable # Run tests via the executables (multi-config paths on macOS/Windows)
./build/bin/yaze_test ./build/bin/Debug/yaze_emu_test --emu_test_rom=roms/alttp_vanilla.sfc
./build/bin/Debug/yaze_test_stable --rom=roms/alttp_vanilla.sfc
./build/bin/Debug/yaze_test_gui --rom=roms/alttp_vanilla.sfc
./build/bin/Debug/yaze_test_benchmark --rom=roms/alttp_vanilla.sfc
# Run only stable tests using CTest labels # Run only stable tests using CTest labels
ctest --test-dir build --label-regex "STABLE" ctest --test-dir build --label-regex "STABLE"
@@ -329,10 +363,10 @@ After pulling major changes or switching branches, your build directory can beco
### Common Issues ### Common Issues
#### "nlohmann/json.hpp: No such file or directory" #### "nlohmann/json.hpp: No such file or directory"
**Cause**: You are building code that requires AI features without using an AI-enabled preset, or your Git submodules are not initialized. **Cause**: You are building code that requires AI features without using an AI-enabled preset, or CMake has not fetched CPM dependencies yet.
**Solution**: **Solution**:
1. Use an AI preset like `win-ai` or `mac-ai`. 1. Use an AI preset like `win-ai` or `mac-ai`.
2. Ensure submodules are present by running `git submodule update --init --recursive`. 2. Reconfigure to fetch dependencies: `cmake --preset <preset>` (or delete the build folder and re-run).
#### "Cannot open file 'yaze.exe': Permission denied" #### "Cannot open file 'yaze.exe': Permission denied"
**Cause**: A previous instance of `yaze.exe` is still running in the background. **Cause**: A previous instance of `yaze.exe` is still running in the background.

View File

@@ -49,45 +49,82 @@ cmake --build --preset win-arm
### macOS Presets ### macOS Presets
| Preset | Description | Arch | Warnings | Features | | Preset | Description | Arch | Warnings | Notes |
|--------|-------------|------|----------|----------| |--------|-------------|------|----------|-------|
| `mac-dbg` | Debug build | ARM64 | Off | Basic | | `mac-dbg` | Debug build | Host | Off | Tests enabled |
| `mac-dbg-v` | Debug verbose | ARM64 | On | Basic | | `mac-dbg-v` | Debug build (verbose) | Host | On | Extra warnings |
| `mac-rel` | Release | ARM64 | Off | Basic | | `mac-rel` | Release build | Host | Off | LTO enabled |
| `mac-x64` | Debug x86_64 | x86_64 | Off | Basic | | `mac-dev` | Development build | Host | Off | ROM tests enabled |
| `mac-uni` | Universal binary | Both | Off | Basic | | `mac-ai` | AI + gRPC dev | Host | Off | Agent UI + automation |
| `mac-dev` | Development | ARM64 | Off | ROM tests | | `mac-ai-fast` | AI dev (system gRPC) | Host | Off | `brew install grpc protobuf abseil` |
| `mac-ai` | AI development | ARM64 | Off | z3ed, JSON, gRPC, ROM tests | | `mac-uni` | Universal binary | arm64 + x86_64 | Off | Release packaging |
| `mac-z3ed` | z3ed CLI | ARM64 | Off | AI agent support | | `mac-sdl3` | SDL3 build | Host | Off | Experimental |
| `mac-rooms` | Dungeon editor | ARM64 | Off | Minimal build for room editing | | `mac-test` | Fast test build | Host | Off | RelWithDebInfo |
### Windows Presets ### Windows Presets
| Preset | Description | Arch | Warnings | Features | | Preset | Description | Arch | Generator | Notes |
|--------|-------------|------|----------|----------| |--------|-------------|------|-----------|-------|
| `win-dbg` | Debug build | x64 | Off | Basic | | `win-dbg` | Debug build | x64 | Ninja | Tests enabled |
| `win-dbg-v` | Debug verbose | x64 | On | Basic | | `win-dbg-v` | Debug build (verbose) | x64 | Ninja | Extra warnings |
| `win-rel` | Release | x64 | Off | Basic | | `win-rel` | Release build | x64 | Ninja | LTO enabled |
| `win-arm` | Debug ARM64 | ARM64 | Off | Basic | | `win-dev` | Development build | x64 | Ninja | ROM tests enabled |
| `win-arm-rel` | Release ARM64 | ARM64 | Off | Basic | | `win-ai` | AI + gRPC dev | x64 | Ninja | Agent UI + automation |
| `win-dev` | Development | x64 | Off | ROM tests | | `win-z3ed` | z3ed CLI | x64 | Ninja | CLI stack only |
| `win-ai` | AI development | x64 | Off | z3ed, JSON, gRPC, ROM tests | | `win-arm` | Debug ARM64 | ARM64 | Ninja | |
| `win-z3ed` | z3ed CLI | x64 | Off | AI agent support | | `win-arm-rel` | Release ARM64 | ARM64 | Ninja | |
| `win-vs-dbg` | Debug build | x64 | Visual Studio | |
| `win-vs-rel` | Release build | x64 | Visual Studio | |
| `win-vs-ai` | AI + gRPC dev | x64 | Visual Studio | |
| `win-sdl3` | SDL3 build | x64 | Ninja | Experimental |
| `win-test` | Fast test build | x64 | Ninja | RelWithDebInfo |
### Linux Presets ### Linux Presets
| Preset | Description | Compiler | Warnings | | Preset | Description | Compiler | Notes |
|--------|-------------|----------|----------| |--------|-------------|----------|-------|
| `lin-dbg` | Debug | GCC | Off | | `lin-dbg` | Debug build | GCC/Clang | Tests enabled |
| `lin-clang` | Debug | Clang | Off | | `lin-dbg-v` | Debug build (verbose) | GCC/Clang | Extra warnings |
| `lin-rel` | Release build | GCC/Clang | LTO enabled |
| `lin-dev` | Development build | GCC/Clang | ROM tests enabled |
| `lin-ai` | AI + gRPC dev | GCC/Clang | Agent UI + automation |
| `lin-sdl3` | SDL3 build | GCC/Clang | Experimental |
| `lin-test` | Fast test build | GCC/Clang | RelWithDebInfo |
### Special Purpose ### CI Presets
| Preset | Description | | Preset | Description |
|--------|-------------| |--------|-------------|
| `ci` | Continuous integration (no ROM tests) | | `ci-linux` | Linux CI build |
| `asan` | AddressSanitizer build | | `ci-macos` | macOS CI build |
| `coverage` | Code coverage build | | `ci-windows` | Windows CI build |
| `ci-windows-ai` | Windows AI/automation CI build |
### WASM Presets
| Preset | Description |
|--------|-------------|
| `wasm-debug` | WebAssembly debug build |
| `wasm-release` | WebAssembly release build |
| `wasm-crash-repro` | Minimal repro build |
| `wasm-ai` | WebAssembly AI build |
### Test Presets
Run with `ctest --preset <name>`.
| Preset | Description |
|--------|-------------|
| `all` | All tests (including ROM-dependent) |
| `stable` | Stable tests only |
| `unit` | Unit tests only |
| `integration` | Integration tests only |
| `fast` | macOS fast test preset |
| `fast-win` | Windows fast test preset |
| `fast-lin` | Linux fast test preset |
| `stable-ai` | Stable tests against `ci-windows-ai` |
| `unit-ai` | Unit tests against `ci-windows-ai` |
| `integration-ai` | Integration tests against `ci-windows-ai` |
## Warning Control ## Warning Control
@@ -104,9 +141,9 @@ By default, all presets suppress compiler warnings with `-w` for a cleaner build
## Architecture Support ## Architecture Support
### macOS ### macOS
- **ARM64 (Apple Silicon)**: `mac-dbg`, `mac-rel`, `mac-ai`, etc. - **Apple Silicon (arm64)**: `mac-dbg`, `mac-rel`, `mac-ai`, `mac-dev`, etc.
- **x86_64 (Intel)**: `mac-x64` - **Intel (x86_64)**: Use the same `mac-*` presets (they target the host arch).
- **Universal Binary**: `mac-uni` (both ARM64 + x86_64) - **Universal Binary**: `mac-uni` (arm64 + x86_64)
### Windows ### Windows
- **x64**: `win-dbg`, `win-rel`, `win-ai`, etc. - **x64**: `win-dbg`, `win-rel`, `win-ai`, etc.
@@ -114,7 +151,19 @@ By default, all presets suppress compiler warnings with `-w` for a cleaner build
## Build Directories ## Build Directories
Most presets use `build/`. WASM presets use `build-wasm/`. Use `CMakeUserPresets.json` for custom directories. Most presets use `build/`. WASM presets use `build-wasm/`. Keep only these two build directories in the repo to avoid bloat. For isolated agent builds, point `binaryDir` to a path outside the repo via `CMakeUserPresets.json`.
### Shared Dependency Caches
To avoid re-downloading dependencies after cleaning build dirs, set shared caches via `CMakeUserPresets.json` (see `CMakeUserPresets.json.example`) or environment variables:
```bash
export CPM_SOURCE_CACHE="$HOME/.cpm-cache"
export VCPKG_DOWNLOADS="$HOME/.cache/vcpkg/downloads"
export VCPKG_BINARY_SOURCES="clear;files,$HOME/.cache/vcpkg/bincache,readwrite"
```
For scripts and the agent build tool, you can also set `YAZE_BUILD_DIR` to an external path (e.g., `$HOME/.cache/yaze/build`) to keep the working tree clean.
## Feature Flags ## Feature Flags
@@ -123,28 +172,29 @@ Common CMake options you can override:
```bash ```bash
# Enable/disable components # Enable/disable components
-DYAZE_BUILD_TESTS=ON/OFF -DYAZE_BUILD_TESTS=ON/OFF
-DYAZE_BUILD_Z3ED=ON/OFF -DYAZE_BUILD_AGENT_UI=ON/OFF
-DYAZE_BUILD_EMU=ON/OFF
-DYAZE_BUILD_APP=ON/OFF
# AI features # AI features
-DZ3ED_AI=ON/OFF -DYAZE_ENABLE_AI=ON/OFF
-DYAZE_WITH_JSON=ON/OFF -DYAZE_ENABLE_AI_RUNTIME=ON/OFF
-DYAZE_WITH_GRPC=ON/OFF -DYAZE_ENABLE_GRPC=ON/OFF
-DYAZE_PREFER_SYSTEM_GRPC=ON/OFF
-DYAZE_ENABLE_JSON=ON/OFF
-DYAZE_ENABLE_REMOTE_AUTOMATION=ON/OFF
# Testing # Testing
-DYAZE_ENABLE_ROM_TESTS=ON/OFF -DYAZE_ENABLE_ROM_TESTS=ON/OFF
-DYAZE_TEST_ROM_PATH=/path/to/zelda3.sfc -DYAZE_TEST_ROM_VANILLA_PATH=/path/to/alttp_vanilla.sfc
-DYAZE_TEST_ROM_EXPANDED_PATH=/path/to/oos168.sfc
# Build optimization -DYAZE_USE_SDL3=ON/OFF
-DYAZE_MINIMAL_BUILD=ON/OFF -DYAZE_ENABLE_LTO=ON/OFF
``` ```
## Examples ## Examples
### Development with AI features and verbose warnings ### Development with AI features and verbose warnings
```bash ```bash
cmake --preset mac-dbg-v -DZ3ED_AI=ON -DYAZE_WITH_GRPC=ON cmake --preset mac-dbg-v -DYAZE_ENABLE_AI=ON -DYAZE_ENABLE_GRPC=ON -DYAZE_BUILD_AGENT_UI=ON
cmake --build --preset mac-dbg-v cmake --build --preset mac-dbg-v
``` ```
@@ -157,7 +207,7 @@ cpack --preset mac-uni
### Quick minimal build for testing ### Quick minimal build for testing
```bash ```bash
cmake --preset mac-dbg -DYAZE_MINIMAL_BUILD=ON cmake --preset mac-dbg -DYAZE_ENABLE_AI=OFF -DYAZE_ENABLE_GRPC=OFF -DYAZE_BUILD_AGENT_UI=OFF
cmake --build --preset mac-dbg -j12 cmake --build --preset mac-dbg -j12
``` ```
@@ -181,12 +231,10 @@ Old preset names have been simplified:
| `macos-debug` | `mac-dbg` | | `macos-debug` | `mac-dbg` |
| `macos-release` | `mac-rel` | | `macos-release` | `mac-rel` |
| `macos-debug-universal` | `mac-uni` | | `macos-debug-universal` | `mac-uni` |
| `macos-dungeon-dev` | `mac-rooms` |
| `windows-debug` | `win-dbg` | | `windows-debug` | `win-dbg` |
| `windows-release` | `win-rel` | | `windows-release` | `win-rel` |
| `windows-arm64-debug` | `win-arm` | | `windows-arm64-debug` | `win-arm` |
| `linux-debug` | `lin-dbg` | | `linux-debug` | `lin-dbg` |
| `linux-clang` | `lin-clang` |
## Troubleshooting ## Troubleshooting
@@ -201,5 +249,6 @@ Old preset names have been simplified:
- Restart your IDE or LSP server - Restart your IDE or LSP server
### Build fails with missing dependencies ### Build fails with missing dependencies
- Ensure submodules are initialized: `git submodule update --init --recursive` - Re-run configure to fetch CPM dependencies: `cmake --preset <your-preset>`
- If offline, set `CPM_SOURCE_CACHE` to a populated cache directory
- For AI features, make sure you have OpenSSL: `brew install openssl` (macOS) - For AI features, make sure you have OpenSSL: `brew install openssl` (macOS)

View File

@@ -27,23 +27,33 @@ Run the verification script once per machine to check dependencies and fix commo
.\scripts\verify-build-environment.ps1 -FixIssues .\scripts\verify-build-environment.ps1 -FixIssues
``` ```
### macOS Toolchain Selection
AppleClang (`/usr/bin/clang`) is the default and most reliable choice. If Homebrew LLVM is on your PATH and you hit SDK header errors, pick the toolchain explicitly:
```bash
# AppleClang (recommended)
cmake --preset mac-dbg --fresh -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++
# Homebrew LLVM (optional)
cmake --preset mac-dbg --fresh -DCMAKE_TOOLCHAIN_FILE=cmake/llvm-brew.toolchain.cmake
```
--- ---
## 2. Build Presets ## 2. Build Presets
YAZE uses CMake presets for consistent builds. Configure with `cmake --preset <name>`, then build with `cmake --build --preset <name>`. YAZE uses CMake presets for consistent builds. Configure with `cmake --preset <name>`, then build with `cmake --build --preset <name>`.
### Available Presets ### Available Presets (High Level)
| Preset | Platform | Description | - **macOS**: `mac-dbg`, `mac-dbg-v`, `mac-rel`, `mac-dev`, `mac-ai`, `mac-ai-fast`, `mac-uni`, `mac-sdl3`, `mac-test`
|--------|----------|-------------| - **Windows**: `win-dbg`, `win-dbg-v`, `win-rel`, `win-dev`, `win-ai`, `win-z3ed`, `win-arm`, `win-arm-rel`, `win-vs-dbg`, `win-vs-rel`, `win-vs-ai`, `win-sdl3`, `win-test`
| `mac-dbg`, `lin-dbg`, `win-dbg` | macOS / Linux / Windows | Standard debug builds with tests enabled | - **Linux**: `lin-dbg`, `lin-dbg-v`, `lin-rel`, `lin-dev`, `lin-ai`, `lin-sdl3`, `lin-test`
| `mac-ai`, `lin-ai`, `win-ai` | macOS / Linux / Windows | Full AI stack: gRPC, agent UI, z3ed CLI, AI runtime | - **CI**: `ci-linux`, `ci-macos`, `ci-windows`, `ci-windows-ai`
| `mac-rel`, `lin-rel`, `win-rel` | macOS / Linux / Windows | Optimized release builds | - **WASM**: `wasm-debug`, `wasm-release`, `wasm-crash-repro`, `wasm-ai`
| `mac-dev`, `lin-dev`, `win-dev` | macOS / Linux / Windows | Development builds with ROM-dependent tests |
| `mac-uni` | macOS | Universal binary (ARM64 + x86_64) for distribution | `mac-ai-fast` prefers the Homebrew gRPC/protobuf stack for faster configure times (`brew install grpc protobuf abseil`).
| `mac-test`, `lin-test`, `win-test` | All | Optimized builds for fast test iteration |
| `ci-*` | Platform-specific | CI/CD configurations (see CMakePresets.json) |
**Tip:** Add `-v` suffix (e.g., `mac-dbg-v`) to enable verbose compiler warnings. **Tip:** Add `-v` suffix (e.g., `mac-dbg-v`) to enable verbose compiler warnings.
@@ -56,7 +66,9 @@ YAZE uses CMake presets for consistent builds. Configure with `cmake --preset <n
| Native (desktop/CLI) | `build/` | | Native (desktop/CLI) | `build/` |
| WASM | `build-wasm/` | | WASM | `build-wasm/` |
If you need per-user or per-agent isolation, create a local `CMakeUserPresets.json` that points `binaryDir` to a custom path. macOS and Windows presets use multi-config generators, so binaries live under `build/bin/Debug` or `build/bin/Release`. Linux uses single-config builds in `build/bin`.
If you need per-user or per-agent isolation, create a local `CMakeUserPresets.json` that points `binaryDir` to a custom path outside the repo. Avoid creating additional `build_*` folders in the repo to keep the checkout small.
Example: Example:
```bash ```bash
@@ -66,11 +78,37 @@ cmake --preset dev-local
cmake --build --preset dev-local --target yaze cmake --build --preset dev-local --target yaze
``` ```
You can also set `YAZE_BUILD_DIR` for scripts and the agent build tool to direct builds to an external path:
```bash
export YAZE_BUILD_DIR="$HOME/.cache/yaze/build"
```
For AI-enabled builds, use the `*-ai` presets and specify only the targets you need: For AI-enabled builds, use the `*-ai` presets and specify only the targets you need:
```bash ```bash
cmake --build --preset mac-ai --target yaze z3ed cmake --build --preset mac-ai --target yaze z3ed
``` ```
### Shared Dependency Caches (Recommended)
Set shared caches once per machine to avoid re-downloading dependencies after
cleaning build directories.
**macOS / Linux:**
```bash
export CPM_SOURCE_CACHE="$HOME/.cpm-cache"
export VCPKG_DOWNLOADS="$HOME/.cache/vcpkg/downloads"
export VCPKG_BINARY_SOURCES="clear;files,$HOME/.cache/vcpkg/bincache,readwrite"
```
**Windows (PowerShell):**
```powershell
$env:CPM_SOURCE_CACHE = "$env:USERPROFILE\.cpm-cache"
$env:VCPKG_DOWNLOADS = "$env:LOCALAPPDATA\vcpkg\downloads"
$env:VCPKG_BINARY_SOURCES = "clear;files,$env:LOCALAPPDATA\vcpkg\bincache,readwrite"
```
You can also set these in `CMakeUserPresets.json` (see `CMakeUserPresets.json.example`).
**Windows Helper Scripts:** **Windows Helper Scripts:**
- Quick builds: `scripts/agents/windows-smoke-build.ps1` - Quick builds: `scripts/agents/windows-smoke-build.ps1`
- Test runs: `scripts/agents/run-tests.sh` (or PowerShell equivalent) - Test runs: `scripts/agents/run-tests.sh` (or PowerShell equivalent)
@@ -138,6 +176,19 @@ ctest --test-dir build --output-on-failure
ctest --test-dir build -R "Dungeon" ctest --test-dir build -R "Dungeon"
``` ```
### Direct Test Binaries
```bash
# macOS/Windows (multi-config)
./build/bin/Debug/yaze_emu_test --emu_test_rom=roms/alttp_vanilla.sfc
./build/bin/Debug/yaze_test_stable --rom=roms/alttp_vanilla.sfc
./build/bin/Debug/yaze_test_gui --rom=roms/alttp_vanilla.sfc
./build/bin/Debug/yaze_test_benchmark --rom=roms/alttp_vanilla.sfc
# Linux (single-config)
./build/bin/yaze_emu_test --emu_test_rom=roms/alttp_vanilla.sfc
```
### Test Categories ### Test Categories
| Category | Command | Description | | Category | Command | Description |
@@ -151,7 +202,7 @@ ctest --test-dir build -R "Dungeon"
```bash ```bash
# Configure with ROM path # Configure with ROM path
cmake --preset mac-dev -DYAZE_TEST_ROM_PATH=/path/to/zelda3.sfc cmake --preset mac-dev -DYAZE_TEST_ROM_VANILLA_PATH="$PWD/roms/alttp_vanilla.sfc"
# Build and run # Build and run
cmake --build --preset mac-dev --target yaze_test cmake --build --preset mac-dev --target yaze_test
@@ -171,7 +222,9 @@ ctest --test-dir build -L rom_dependent
| Variable | Purpose | | Variable | Purpose |
|----------|---------| |----------|---------|
| `YAZE_TEST_ROM_PATH` | Path to ROM for ROM-dependent tests | | `YAZE_TEST_ROM_VANILLA` | Path to vanilla ROM for ROM-dependent tests |
| `YAZE_TEST_ROM_EXPANDED` | Path to expanded (ZSCustom/OOS) ROM |
| `YAZE_TEST_ROM_PATH` | Legacy ROM path (vanilla fallback) |
| `YAZE_SKIP_ROM_TESTS` | Skip ROM tests (useful for CI) | | `YAZE_SKIP_ROM_TESTS` | Skip ROM tests (useful for CI) |
| `YAZE_ENABLE_UI_TESTS` | Enable GUI tests (auto-detected if display available) | | `YAZE_ENABLE_UI_TESTS` | Enable GUI tests (auto-detected if display available) |

View File

@@ -1,12 +1,13 @@
# YAZE Build Troubleshooting Guide # YAZE Build Troubleshooting Guide
**Last Updated**: October 2025 **Last Updated**: December 2025
**Related Docs**: BUILD-GUIDE.md, ci-cd/CI-SETUP.md **Related Docs**: quick-reference.md, build-from-source.md, presets.md
## Table of Contents ## Table of Contents
- [gRPC ARM64 Issues](#grpc-arm64-issues) - [gRPC ARM64 Issues](#grpc-arm64-issues)
- [Windows Build Issues](#windows-build-issues) - [Windows Build Issues](#windows-build-issues)
- [macOS Issues](#macos-issues) - [macOS Issues](#macos-issues)
- [Disk Usage and Build Directory Bloat](#disk-usage-and-build-directory-bloat)
- [Linux Issues](#linux-issues) - [Linux Issues](#linux-issues)
- [Common Build Errors](#common-build-errors) - [Common Build Errors](#common-build-errors)
@@ -14,127 +15,43 @@
## gRPC ARM64 Issues ## gRPC ARM64 Issues
### Status: Known Issue with Workarounds ### Preferred Path: System gRPC on macOS
The ARM64 macOS build has persistent issues with Abseil's random number generation targets when building gRPC from source. This issue has been ongoing through multiple attempts to fix. On Apple Silicon, the fastest and most reliable setup is Homebrew's gRPC stack:
### The Problem
**Error**:
```
clang++: error: unsupported option '-msse4.1' for target 'arm64-apple-darwin25.0.0'
```
**Target**: `absl_random_internal_randen_hwaes_impl`
**Root Cause**: Abseil's random number generation targets are being built with x86-specific compiler flags (`-msse4.1`, `-maes`, `-msse4.2`) on ARM64 macOS.
### Working Configuration
**gRPC Version**: v1.67.1 (tested and stable)
**Protobuf Version**: 3.28.1 (bundled with gRPC)
**Abseil Version**: 20240116.0 (bundled with gRPC)
### Solution Approaches Tried
#### ❌ Failed Attempts
1. **CMake flag configuration** - Abseil variables being overridden by gRPC
2. **Global CMAKE_CXX_FLAGS** - Flags set at target level, not global
3. **Pre-configuration Abseil settings** - gRPC overrides them
4. **Different gRPC versions** - v1.62.0, v1.68.0, v1.60.0, v1.58.0 all have issues
#### ✅ Working Approach: Target Property Manipulation
The working solution involves manipulating target properties after gRPC is configured:
```cmake
# In cmake/grpc.cmake (from working commit 6db7ba4782)
if(APPLE AND CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
# List of Abseil targets with x86-specific flags
set(_absl_targets_with_x86_flags
absl_random_internal_randen_hwaes_impl
absl_random_internal_randen_hwaes
absl_crc_internal_cpu_detect
)
foreach(_absl_target IN LISTS _absl_targets_with_x86_flags)
if(TARGET ${_absl_target})
get_target_property(_absl_opts ${_absl_target} COMPILE_OPTIONS)
if(_absl_opts)
# Remove SSE flags: -maes, -msse4.1, -msse2, -Xarch_x86_64
list(FILTER _absl_opts EXCLUDE REGEX "^-m(aes|sse)")
list(FILTER _absl_opts EXCLUDE REGEX "^-Xarch_x86_64")
set_property(TARGET ${_absl_target} PROPERTY COMPILE_OPTIONS ${_absl_opts})
endif()
endif()
endforeach()
endif()
```
### Current Workaround
**Option 1**: Use the bundled Abseil with target property manipulation (as above)
**Option 2**: Disable gRPC for ARM64 development
```cmake
if(APPLE AND CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
set(YAZE_WITH_GRPC OFF CACHE BOOL "" FORCE)
message(STATUS "ARM64: Disabling gRPC due to build issues")
endif()
```
**Option 3**: Use pre-built vcpkg packages (Windows-style approach for macOS)
```bash ```bash
brew install grpc protobuf abseil brew install grpc protobuf abseil
# Then use find_package instead of FetchContent cmake --preset mac-ai-fast
``` ```
### Environment Configuration You can also force it in any preset with `-DYAZE_PREFER_SYSTEM_GRPC=ON`.
**Homebrew LLVM Configuration**: ### If You Must Build gRPC From Source
- **Toolchain**: `cmake/llvm-brew.toolchain.cmake`
- **SDK**: `/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk`
- **C++ Standard Library**: Homebrew's libc++ (not system libstdc++)
### Build Commands for Testing When building gRPC/Abseil from source on ARM64, x86-only SSE flags can still surface. If you see errors like:
```
clang++: error: unsupported option '-msse4.1' for target 'arm64-apple-darwin...'
```
switch to system gRPC (`YAZE_PREFER_SYSTEM_GRPC=ON`) or disable gRPC for that build:
```bash ```bash
# Clean build cmake --preset mac-dbg -DYAZE_ENABLE_GRPC=OFF
rm -rf build/_deps/grpc-build
# Test configuration
cmake --preset mac-dbg
# Test build
cmake --build --preset mac-dbg --target protoc
``` ```
### Success Criteria ### Toolchain Consistency (AppleClang vs Homebrew LLVM)
If Homebrew LLVM is on your PATH, SDK headers can be picked up in the wrong order and cause missing type errors. Either:
The build succeeds when:
```bash ```bash
cmake --build --preset mac-dbg --target protoc # Force AppleClang
# Returns exit code 0 (no SSE flag errors) cmake --preset mac-dbg --fresh -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++
# Or use the Homebrew LLVM toolchain file
cmake --preset mac-dbg --fresh -DCMAKE_TOOLCHAIN_FILE=cmake/llvm-brew.toolchain.cmake
``` ```
### Files to Monitor
**Critical Files**:
- `cmake/grpc.cmake` - Main gRPC configuration
- `build/_deps/grpc-build/third_party/abseil-cpp/` - Abseil build output
- `build/_deps/grpc-build/third_party/abseil-cpp/absl/random/CMakeFiles/` - Random target build files
**Log Files**:
- CMake configuration output (look for Abseil configuration messages)
- Build output (look for compiler flag errors)
- `build/_deps/grpc-build/CMakeCache.txt` - Check if ARM64 flags are set
### Additional Resources
- **gRPC ARM64 Issues**: https://github.com/grpc/grpc/issues (search for ARM64, macOS, Abseil)
- **Abseil Random Documentation**: https://abseil.io/docs/cpp/guides/random
- **CMake FetchContent**: https://cmake.org/cmake/help/latest/module/FetchContent.html
--- ---
## Windows Build Issues ## Windows Build Issues
@@ -282,6 +199,18 @@ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
--- ---
## Disk Usage and Build Directory Bloat
If the repository grows unexpectedly large, check for extra build directories in the repo root. The supported in-repo directories are `build/` and `build-wasm/`. Move any additional builds to an external path via `CMakeUserPresets.json` or `YAZE_BUILD_DIR`, then delete the old folders:
```bash
rm -rf build_agent build_agent_llvm build_agent_ninja build_gemini
```
Keeping CPM/vcpkg caches in `~/.cache` or `~/.cpm-cache` prevents re-downloading after cleanups.
---
## Linux Issues ## Linux Issues
### Missing Dependencies ### Missing Dependencies

View File

@@ -2,6 +2,7 @@
# scripts/gemini_build.sh # scripts/gemini_build.sh
# Build script for Gemini AI agent - builds full yaze with all features # Build script for Gemini AI agent - builds full yaze with all features
# Usage: ./scripts/gemini_build.sh [target] [--fresh] # Usage: ./scripts/gemini_build.sh [target] [--fresh]
# Optional: set YAZE_BUILD_DIR to override the build directory.
# #
# Examples: # Examples:
# ./scripts/gemini_build.sh # Build yaze (default) # ./scripts/gemini_build.sh # Build yaze (default)
@@ -12,7 +13,7 @@
set -e set -e
# Configuration # Configuration
BUILD_DIR="build_gemini" BUILD_DIR="${YAZE_BUILD_DIR:-build}"
PRESET="mac-gemini" PRESET="mac-gemini"
TARGET="${1:-yaze}" TARGET="${1:-yaze}"
FRESH="" FRESH=""

View File

@@ -2,6 +2,7 @@
#include <array> #include <array>
#include <cstdio> #include <cstdio>
#include <cstdlib>
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <future> #include <future>
@@ -39,8 +40,11 @@ namespace fs = std::filesystem;
BuildTool::BuildTool(const BuildConfig& config) BuildTool::BuildTool(const BuildConfig& config)
: config_(config) { : config_(config) {
// Ensure build directory is set with a default value // Ensure build directory is set with a default value
if (config_.build_directory.empty()) { const char* env_build_dir = std::getenv("YAZE_BUILD_DIR");
config_.build_directory = "build_ai"; if (env_build_dir != nullptr && env_build_dir[0] != '\0') {
config_.build_directory = env_build_dir;
} else if (config_.build_directory.empty()) {
config_.build_directory = "build";
} }
// Convert to absolute path if relative // Convert to absolute path if relative
@@ -171,9 +175,13 @@ absl::StatusOr<BuildTool::BuildResult> BuildTool::RunTests(
absl::StrFormat("ROM file not found: %s", rom_path)); absl::StrFormat("ROM file not found: %s", rom_path));
} }
#ifdef _WIN32 #ifdef _WIN32
env_setup = absl::StrFormat("set YAZE_TEST_ROM_PATH=\"%s\" && ", rom_path); env_setup = absl::StrFormat(
"set YAZE_TEST_ROM_VANILLA=\"%s\" && set YAZE_TEST_ROM_PATH=\"%s\" && ",
rom_path, rom_path);
#else #else
env_setup = absl::StrFormat("YAZE_TEST_ROM_PATH=\"%s\" ", rom_path); env_setup = absl::StrFormat(
"YAZE_TEST_ROM_VANILLA=\"%s\" YAZE_TEST_ROM_PATH=\"%s\" ",
rom_path, rom_path);
#endif #endif
} }

View File

@@ -33,26 +33,26 @@ class BuildTool {
public: public:
// Build operation results // Build operation results
struct BuildResult { struct BuildResult {
bool success; bool success = false;
std::string output; std::string output;
std::string error_output; std::string error_output;
int exit_code; int exit_code = 0;
std::chrono::seconds duration; std::chrono::seconds duration{0};
std::string command_executed; std::string command_executed;
}; };
// Build status information // Build status information
struct BuildStatus { struct BuildStatus {
bool is_running; bool is_running = false;
std::string current_operation; std::string current_operation;
std::string last_result_summary; std::string last_result_summary;
std::chrono::system_clock::time_point start_time; std::chrono::system_clock::time_point start_time{};
int progress_percent; // -1 if unknown int progress_percent = 0; // -1 if unknown
}; };
// Build configuration // Build configuration
struct BuildConfig { struct BuildConfig {
std::string build_directory = "build_ai"; // Default AI agent build dir std::string build_directory = "build"; // Override via YAZE_BUILD_DIR
std::chrono::seconds timeout = std::chrono::seconds(600); // 10 min default std::chrono::seconds timeout = std::chrono::seconds(600); // 10 min default
bool capture_output = true; bool capture_output = true;
bool verbose = false; bool verbose = false;