From cadda0d446c1e77dacc859534f22895fafdb4eb7 Mon Sep 17 00:00:00 2001 From: scawful Date: Thu, 2 Oct 2025 19:49:06 -0400 Subject: [PATCH] Enhance build environment verification with comprehensive scripts - Added `verify-build-environment.ps1` for Windows users to check CMake, Git, Visual Studio, and submodules, with options for verbose output, automatic fixes, and cache cleaning. - Introduced `verify-build-environment.sh` for macOS/Linux users, providing similar functionality with detailed output and automatic issue resolution. - Updated documentation to include new verification steps and usage instructions for both scripts. - Improved dependency checks and cache management in both scripts to ensure a smooth build setup. --- docs/02-build-instructions.md | 153 +++++++++- scripts/README_VERIFICATION.md | 321 +++++++++++++++++++++ scripts/verify-build-environment.ps1 | 369 ++++++++++++++++++++++++ scripts/verify-build-environment.sh | 401 +++++++++++++++++++++++++++ 4 files changed, 1240 insertions(+), 4 deletions(-) create mode 100644 scripts/README_VERIFICATION.md create mode 100644 scripts/verify-build-environment.ps1 create mode 100755 scripts/verify-build-environment.sh diff --git a/docs/02-build-instructions.md b/docs/02-build-instructions.md index 7ba1e0d4..fd942249 100644 --- a/docs/02-build-instructions.md +++ b/docs/02-build-instructions.md @@ -2,22 +2,74 @@ YAZE uses CMake 3.16+ with modern target-based configuration. The project includes comprehensive Windows support with Visual Studio integration, vcpkg package management, and automated setup scripts. +## ⚡ Build Environment Verification + +**Before building for the first time, run the verification script to ensure your environment is properly configured:** + +### Windows (PowerShell) +```powershell +.\scripts\verify-build-environment.ps1 + +# With automatic fixes +.\scripts\verify-build-environment.ps1 -FixIssues + +# Clean CMake cache +.\scripts\verify-build-environment.ps1 -CleanCache + +# Verbose output +.\scripts\verify-build-environment.ps1 -Verbose +``` + +### macOS/Linux +```bash +./scripts/verify-build-environment.sh + +# With automatic fixes +./scripts/verify-build-environment.sh --fix + +# Clean CMake cache +./scripts/verify-build-environment.sh --clean + +# Verbose output +./scripts/verify-build-environment.sh --verbose +``` + +**The verification script checks:** +- ✓ CMake 3.16+ installation +- ✓ Git and submodule synchronization +- ✓ C++ compiler (GCC 13+, Clang 16+, MSVC 2019+) +- ✓ Platform-specific dependencies (GTK+3 on Linux, Xcode on macOS) +- ✓ CMake cache freshness +- ✓ Dependency compatibility (gRPC, httplib, nlohmann/json) +- ✓ Visual Studio 2022 detection (Windows only) + ## Quick Start ### macOS (Apple Silicon) ```bash +# Verify environment first +./scripts/verify-build-environment.sh + +# Build cmake --preset debug cmake --build build ``` ### Linux ```bash +# Verify environment first +./scripts/verify-build-environment.sh + +# Build cmake -B build -DCMAKE_BUILD_TYPE=Debug cmake --build build ``` ### Windows (Visual Studio CMake Workflow) ```powershell +# Verify environment first +.\scripts\verify-build-environment.ps1 + # Recommended: Use Visual Studio's built-in CMake support # 1. Open Visual Studio 2022 # 2. Select "Open a local folder" @@ -44,10 +96,43 @@ cmake --build build - C++23 compiler (GCC 13+, Clang 16+, MSVC 2019+) - Git with submodule support -### Bundled Libraries -- SDL2, ImGui, Abseil, Asar, GoogleTest -- Native File Dialog Extended (NFD) -- All dependencies included in repository +### Bundled Libraries (Header-Only & Source) +**Core Libraries:** +- **SDL2** - Graphics and input handling +- **ImGui** - Immediate mode GUI framework +- **Abseil** - Google's C++ standard library extensions +- **Asar** - 65816 assembler for SNES +- **GoogleTest** - C++ testing framework + +**Third-Party Header-Only Libraries:** +- **nlohmann/json** (third_party/json) - Modern C++ JSON library +- **cpp-httplib** (third_party/httplib) - HTTP client/server library + +**Optional Libraries:** +- **Native File Dialog Extended (NFD)** - Native file dialogs (excluded in minimal builds) +- **gRPC** - Remote procedure call framework (optional, disabled by default) + +### Dependency Isolation + +YAZE uses careful dependency isolation to prevent conflicts: + +**gRPC Configuration (when enabled with -DYAZE_WITH_GRPC=ON):** +- Uses FetchContent to build from source +- Isolated from system protobuf/abseil installations +- Automatically disables system package detection +- Compatible with Clang 18 and C++23 + +**Header-Only Libraries:** +- nlohmann/json and cpp-httplib are header-only +- No linking required, zero binary conflicts +- Included via git submodules in third_party/ + +**Submodule Management:** +All dependencies are included as git submodules for: +- ✅ Version consistency across all platforms +- ✅ No external package manager required +- ✅ Reproducible builds +- ✅ Offline development capability ## Platform Setup @@ -397,6 +482,66 @@ All Windows CI/CD builds include automatic fallback mechanisms: ## Troubleshooting +### Build Environment Issues + +**CMake Configuration Fails:** +```bash +# Run verification script to diagnose +./scripts/verify-build-environment.sh --verbose + +# Common fixes +git submodule update --init --recursive +./scripts/verify-build-environment.sh --clean --fix +``` + +**Git Submodules Missing or Out of Sync:** +```bash +# Sync and update all submodules +git submodule sync --recursive +git submodule update --init --recursive + +# Verify submodules are present +./scripts/verify-build-environment.sh +``` + +**Old CMake Cache Causing Issues:** +```bash +# Clean cache with verification script +./scripts/verify-build-environment.sh --clean + +# Or manually +rm -rf build build_test build-grpc-test +cmake -B build -DCMAKE_BUILD_TYPE=Debug +``` + +### Dependency Conflicts + +**gRPC Conflicts with System Packages:** +The project automatically isolates gRPC (when enabled) from system packages: +- `CMAKE_DISABLE_FIND_PACKAGE_Protobuf=TRUE` +- `CMAKE_DISABLE_FIND_PACKAGE_absl=TRUE` +- gRPC builds its own protobuf and abseil + +**If you see protobuf/abseil version conflicts:** +```bash +# Verify isolation is configured +grep CMAKE_DISABLE_FIND_PACKAGE cmake/grpc.cmake + +# Clean and reconfigure +./scripts/verify-build-environment.sh --clean --fix +``` + +**httplib or nlohmann/json Missing:** +These are header-only libraries in git submodules: +```bash +# Update submodules +git submodule update --init third_party/json third_party/httplib + +# Verify +ls -la third_party/json/include/ +ls -la third_party/httplib/httplib.h +``` + ### Windows CMake Issues **CMake Not Found:** diff --git a/scripts/README_VERIFICATION.md b/scripts/README_VERIFICATION.md new file mode 100644 index 00000000..7a9d4d26 --- /dev/null +++ b/scripts/README_VERIFICATION.md @@ -0,0 +1,321 @@ +# YAZE Build Environment Verification Scripts + +This directory contains build environment verification and setup scripts for YAZE development. + +## Quick Start + +### Verify Build Environment + +**Windows (PowerShell):** +```powershell +.\scripts\verify-build-environment.ps1 +``` + +**macOS/Linux:** +```bash +./scripts/verify-build-environment.sh +``` + +## Scripts Overview + +### `verify-build-environment.ps1` / `.sh` + +Comprehensive build environment verification script that checks: + +- ✅ **CMake Installation** - Version 3.16+ required +- ✅ **Git Installation** - With submodule support +- ✅ **C++ Compiler** - GCC 13+, Clang 16+, or MSVC 2019+ +- ✅ **Platform Tools** - Xcode (macOS), Visual Studio (Windows), build-essential (Linux) +- ✅ **Git Submodules** - All dependencies synchronized +- ✅ **CMake Cache** - Freshness check (warns if >7 days old) +- ✅ **Dependency Compatibility** - gRPC isolation, httplib, nlohmann/json +- ✅ **CMake Configuration** - Test configuration (verbose mode only) + +#### Usage + +**Windows:** +```powershell +# Basic verification +.\scripts\verify-build-environment.ps1 + +# With automatic fixes (sync submodules, clean cache) +.\scripts\verify-build-environment.ps1 -FixIssues + +# Clean old CMake cache files +.\scripts\verify-build-environment.ps1 -CleanCache + +# Verbose output (includes CMake configuration test) +.\scripts\verify-build-environment.ps1 -Verbose + +# Combined options +.\scripts\verify-build-environment.ps1 -FixIssues -Verbose +``` + +**macOS/Linux:** +```bash +# Basic verification +./scripts/verify-build-environment.sh + +# With automatic fixes +./scripts/verify-build-environment.sh --fix + +# Clean old CMake cache files +./scripts/verify-build-environment.sh --clean + +# Verbose output +./scripts/verify-build-environment.sh --verbose + +# Combined options +./scripts/verify-build-environment.sh --fix --verbose +``` + +#### Exit Codes + +- `0` - Success, environment ready for development +- `1` - Issues found, manual intervention required + +## Common Workflows + +### First-Time Setup + +```bash +# 1. Clone repository with submodules +git clone --recursive https://github.com/scawful/yaze.git +cd yaze + +# 2. Verify environment +./scripts/verify-build-environment.sh --verbose + +# 3. If issues found, fix automatically +./scripts/verify-build-environment.sh --fix + +# 4. Build +cmake --preset debug # macOS +# OR +cmake -B build -DCMAKE_BUILD_TYPE=Debug # All platforms +cmake --build build +``` + +### After Pulling Changes + +```bash +# 1. Update submodules +git submodule update --init --recursive + +# 2. Verify environment (check cache age) +./scripts/verify-build-environment.sh + +# 3. If cache is old, clean and rebuild +./scripts/verify-build-environment.sh --clean +cmake -B build -DCMAKE_BUILD_TYPE=Debug +cmake --build build +``` + +### Troubleshooting Build Issues + +```bash +# 1. Clean everything and verify +./scripts/verify-build-environment.sh --clean --fix --verbose + +# 2. This will: +# - Sync all git submodules +# - Remove old CMake cache +# - Test CMake configuration +# - Report any issues + +# 3. Follow recommended actions in output +``` + +### Before Opening Pull Request + +```bash +# Verify clean build environment +./scripts/verify-build-environment.sh --verbose + +# Should report: "Build Environment Ready for Development!" +``` + +## Integration with Visual Studio + +The verification script integrates with Visual Studio CMake workflow: + +1. **Pre-Build Check**: Run verification before opening VS +2. **Submodule Sync**: Ensures all dependencies are present +3. **Cache Management**: Prevents stale CMake cache issues + +**Visual Studio Workflow:** +```powershell +# 1. Verify environment +.\scripts\verify-build-environment.ps1 -Verbose + +# 2. Open in Visual Studio +# File → Open → Folder → Select yaze directory + +# 3. Visual Studio detects CMakeLists.txt automatically +# 4. Select Debug/Release from toolbar +# 5. Press F5 to build and run +``` + +## What Gets Checked + +### CMake (Required) +- Minimum version 3.16 +- Command available in PATH +- Compatible with project CMake files + +### Git (Required) +- Git command available +- Submodule support +- All submodules present and synchronized: + - `src/lib/SDL` + - `src/lib/abseil-cpp` + - `src/lib/asar` + - `src/lib/imgui` + - `third_party/json` + - `third_party/httplib` + +### Compilers (Required) +- **Windows**: Visual Studio 2019+ with C++ workload +- **macOS**: Xcode Command Line Tools +- **Linux**: GCC 13+ or Clang 16+, build-essential package + +### Platform Dependencies + +**Linux Specific:** +- GTK+3 development libraries (`libgtk-3-dev`) +- DBus development libraries (`libdbus-1-dev`) +- pkg-config tool + +**macOS Specific:** +- Xcode Command Line Tools +- Cocoa framework (automatic) + +**Windows Specific:** +- Visual Studio 2022 recommended +- Windows SDK 10.0.19041.0 or later + +### CMake Cache + +Checks for build directories: +- `build/` - Main build directory +- `build_test/` - Test build directory +- `build-grpc-test/` - gRPC test builds +- `out/` - Visual Studio CMake output + +Warns if cache files are older than 7 days. + +### Dependencies + +**gRPC Isolation (when enabled):** +- Verifies `CMAKE_DISABLE_FIND_PACKAGE_Protobuf=TRUE` +- Verifies `CMAKE_DISABLE_FIND_PACKAGE_absl=TRUE` +- Prevents system package conflicts + +**Header-Only Libraries:** +- `third_party/httplib` - cpp-httplib HTTP library +- `third_party/json` - nlohmann/json library + +## Automatic Fixes + +When run with `--fix` or `-FixIssues`: + +1. **Sync Git Submodules** + ```bash + git submodule sync --recursive + git submodule update --init --recursive + ``` + +2. **Clean CMake Cache** (when combined with `--clean`) + - Removes `build/`, `build_test/`, `build-grpc-test/` + - Removes Visual Studio cache (`out/`) + +3. **Test CMake Configuration** + - Creates temporary build directory + - Tests minimal configuration + - Reports success/failure + - Cleans up test directory + +## CI/CD Integration + +The verification script can be integrated into CI/CD pipelines: + +```yaml +# Example GitHub Actions step +- name: Verify Build Environment + run: | + ./scripts/verify-build-environment.sh --verbose + shell: bash +``` + +## Troubleshooting + +### Script Reports "CMake Not Found" + +**Windows:** +```powershell +# Check if CMake is installed +cmake --version + +# If not found, add to PATH or install +choco install cmake + +# Restart PowerShell +``` + +**macOS/Linux:** +```bash +# Check if CMake is installed +cmake --version + +# Install if missing +brew install cmake # macOS +sudo apt install cmake # Ubuntu/Debian +``` + +### "Git Submodules Missing" + +```bash +# Manually sync and update +git submodule sync --recursive +git submodule update --init --recursive + +# Or use fix option +./scripts/verify-build-environment.sh --fix +``` + +### "CMake Cache Too Old" + +```bash +# Clean automatically +./scripts/verify-build-environment.sh --clean + +# Or manually +rm -rf build build_test build-grpc-test +``` + +### "Visual Studio Not Found" (Windows) + +```powershell +# Install Visual Studio 2022 with C++ workload +# Download from: https://visualstudio.microsoft.com/ + +# Required workload: +# "Desktop development with C++" +``` + +### Script Fails on Network Issues (gRPC) + +The script verifies configuration but doesn't download gRPC unless building with `-DYAZE_WITH_GRPC=ON`. + +If you encounter network issues: +```bash +# Use minimal build (no gRPC) +cmake -B build -DYAZE_MINIMAL_BUILD=ON +``` + +## See Also + +- [Build Instructions](../docs/02-build-instructions.md) - Complete build guide +- [Getting Started](../docs/01-getting-started.md) - First-time setup +- [Platform Compatibility](../docs/B2-platform-compatibility.md) - Platform-specific notes +- [Contributing](../docs/B1-contributing.md) - Development guidelines diff --git a/scripts/verify-build-environment.ps1 b/scripts/verify-build-environment.ps1 new file mode 100644 index 00000000..0221e1fb --- /dev/null +++ b/scripts/verify-build-environment.ps1 @@ -0,0 +1,369 @@ +# YAZE Build Environment Verification Script for Windows/Visual Studio CMake Users +# This script verifies the build environment is properly configured and ready to build +# Run this before building to catch common configuration issues early + +param( + [switch]$Verbose, + [switch]$FixIssues, + [switch]$CleanCache +) + +$ErrorActionPreference = "Continue" +$script:issuesFound = @() +$script:warnings = @() +$script:success = @() + +function Write-Status { + param($Message, $Type = "Info") + $timestamp = Get-Date -Format "HH:mm:ss" + switch ($Type) { + "Success" { Write-Host "[$timestamp] ✓ " -ForegroundColor Green -NoNewline; Write-Host $Message } + "Error" { Write-Host "[$timestamp] ✗ " -ForegroundColor Red -NoNewline; Write-Host $Message } + "Warning" { Write-Host "[$timestamp] ⚠ " -ForegroundColor Yellow -NoNewline; Write-Host $Message } + "Info" { Write-Host "[$timestamp] ℹ " -ForegroundColor Cyan -NoNewline; Write-Host $Message } + "Step" { Write-Host "`n[$timestamp] ▶ " -ForegroundColor Blue -NoNewline; Write-Host $Message -ForegroundColor White } + } +} + +function Test-Command { + param($Command) + try { + if (Get-Command $Command -ErrorAction SilentlyContinue) { + return $true + } + } catch { + return $false + } + return $false +} + +function Get-CMakeVersion { + try { + $output = & cmake --version 2>&1 + if ($output -match "cmake version (\d+\.\d+\.\d+)") { + return $matches[1] + } + } catch { + return $null + } + return $null +} + +function Test-GitSubmodules { + $submodules = @( + "src/lib/SDL", + "src/lib/abseil-cpp", + "src/lib/asar", + "src/lib/imgui", + "third_party/json", + "third_party/httplib" + ) + + $allPresent = $true + foreach ($submodule in $submodules) { + $path = Join-Path $PSScriptRoot ".." $submodule + if (-not (Test-Path $path)) { + Write-Status "Submodule missing: $submodule" "Error" + $script:issuesFound += "Missing submodule: $submodule" + $allPresent = $false + } elseif ((Get-ChildItem $path -Force | Measure-Object).Count -eq 0) { + Write-Status "Submodule empty: $submodule" "Error" + $script:issuesFound += "Empty submodule: $submodule (run git submodule update)" + $allPresent = $false + } elseif ($Verbose) { + Write-Status "Submodule found: $submodule" "Success" + } + } + return $allPresent +} + +function Test-CMakeCache { + $buildDirs = @("build", "build_test", "build-grpc-test", "out/build") + $cacheIssues = $false + + foreach ($dir in $buildDirs) { + $cachePath = Join-Path $PSScriptRoot ".." $dir "CMakeCache.txt" + if (Test-Path $cachePath) { + $cacheAge = (Get-Date) - (Get-Item $cachePath).LastWriteTime + if ($cacheAge.TotalDays -gt 7) { + Write-Status "CMake cache in '$dir' is $([math]::Round($cacheAge.TotalDays)) days old" "Warning" + $script:warnings += "Old CMake cache in $dir (consider cleaning)" + $cacheIssues = $true + } elseif ($Verbose) { + Write-Status "CMake cache in '$dir' is recent" "Success" + } + } + } + return -not $cacheIssues +} + +function Test-DependencyCompatibility { + Write-Status "Testing dependency configuration..." "Step" + + # Check for potential conflicts + $conflicts = @() + + # Check if grpc is enabled but might conflict with system packages + $grpcPath = Join-Path $PSScriptRoot ".." "cmake" "grpc.cmake" + if (Test-Path $grpcPath) { + $grpcContent = Get-Content $grpcPath -Raw + if ($grpcContent -match "CMAKE_DISABLE_FIND_PACKAGE_Protobuf TRUE") { + Write-Status "gRPC isolation configured correctly" "Success" + } else { + Write-Status "gRPC may conflict with system protobuf" "Warning" + $script:warnings += "gRPC not properly isolated from system packages" + } + } + + # Check httplib configuration + $httplibPath = Join-Path $PSScriptRoot ".." "third_party" "httplib" "CMakeLists.txt" + if (Test-Path $httplibPath) { + Write-Status "httplib found in third_party" "Success" + $script:success += "httplib header-only library available" + } + + # Check json library + $jsonPath = Join-Path $PSScriptRoot ".." "third_party" "json" "include" + if (Test-Path $jsonPath) { + Write-Status "nlohmann/json found in third_party" "Success" + $script:success += "nlohmann/json header-only library available" + } + + return $conflicts.Count -eq 0 +} + +function Clean-CMakeCache { + Write-Status "Cleaning CMake cache..." "Step" + + $buildDirs = @("build", "build_test", "build-grpc-test") + foreach ($dir in $buildDirs) { + $fullPath = Join-Path $PSScriptRoot ".." $dir + if (Test-Path $fullPath) { + Write-Status "Removing $dir..." "Info" + Remove-Item -Recurse -Force $fullPath -ErrorAction SilentlyContinue + } + } + + # Also clean Visual Studio CMake cache + $vsCache = Join-Path $PSScriptRoot ".." "out" + if (Test-Path $vsCache) { + Write-Status "Removing Visual Studio CMake cache (out/)..." "Info" + Remove-Item -Recurse -Force $vsCache -ErrorAction SilentlyContinue + } + + Write-Status "CMake cache cleaned" "Success" +} + +function Sync-GitSubmodules { + Write-Status "Syncing git submodules..." "Step" + + Push-Location (Join-Path $PSScriptRoot "..") + try { + Write-Status "Running: git submodule sync --recursive" "Info" + git submodule sync --recursive + + Write-Status "Running: git submodule update --init --recursive" "Info" + git submodule update --init --recursive + + Write-Status "Submodules synced successfully" "Success" + return $true + } catch { + Write-Status "Failed to sync submodules: $_" "Error" + return $false + } finally { + Pop-Location + } +} + +function Test-CMakeConfiguration { + Write-Status "Testing CMake configuration..." "Step" + + $testBuildDir = Join-Path $PSScriptRoot ".." "build_test_config" + + try { + # Test basic CMake configuration + Write-Status "Configuring CMake (this may take a moment)..." "Info" + $output = & cmake -B $testBuildDir -S (Join-Path $PSScriptRoot "..") ` + -DCMAKE_BUILD_TYPE=Debug ` + -DYAZE_MINIMAL_BUILD=ON ` + -DYAZE_BUILD_TESTS=OFF ` + 2>&1 + + if ($LASTEXITCODE -eq 0) { + Write-Status "CMake configuration successful" "Success" + $script:success += "CMake configuration test passed" + + # Cleanup test build + if (Test-Path $testBuildDir) { + Remove-Item -Recurse -Force $testBuildDir -ErrorAction SilentlyContinue + } + return $true + } else { + Write-Status "CMake configuration failed (exit code: $LASTEXITCODE)" "Error" + if ($Verbose) { + Write-Status "CMake output:" "Info" + $output | ForEach-Object { Write-Host " $_" -ForegroundColor Gray } + } + $script:issuesFound += "CMake configuration test failed (see output with -Verbose)" + return $false + } + } catch { + Write-Status "CMake configuration test failed: $_" "Error" + $script:issuesFound += "CMake test exception: $_" + return $false + } +} + +# ============================================================================ +# Main Verification Process +# ============================================================================ + +Write-Host "`n╔════════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan +Write-Host "║ YAZE Build Environment Verification for Visual Studio CMake ║" -ForegroundColor Cyan +Write-Host "╚════════════════════════════════════════════════════════════════╝`n" -ForegroundColor Cyan + +$startTime = Get-Date + +# Step 1: Check CMake +Write-Status "Checking CMake installation..." "Step" +if (Test-Command "cmake") { + $cmakeVersion = Get-CMakeVersion + Write-Status "CMake found: version $cmakeVersion" "Success" + + $major, $minor = $cmakeVersion.Split('.')[0..1] + if ([int]$major -lt 3 -or ([int]$major -eq 3 -and [int]$minor -lt 16)) { + Write-Status "CMake version too old (need 3.16+)" "Error" + $script:issuesFound += "CMake version $cmakeVersion is below minimum 3.16" + } +} else { + Write-Status "CMake not found in PATH" "Error" + $script:issuesFound += "CMake not installed or not in PATH" +} + +# Step 2: Check Git +Write-Status "Checking Git installation..." "Step" +if (Test-Command "git") { + $gitVersion = (& git --version) -replace "git version ", "" + Write-Status "Git found: version $gitVersion" "Success" +} else { + Write-Status "Git not found in PATH" "Error" + $script:issuesFound += "Git not installed or not in PATH" +} + +# Step 3: Check Visual Studio +Write-Status "Checking Visual Studio installation..." "Step" +$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" +if (Test-Path $vswhere) { + $vsInstances = & $vswhere -latest -format json | ConvertFrom-Json + if ($vsInstances) { + # Handle both single instance and array returns + $vsInstance = if ($vsInstances -is [array]) { $vsInstances[0] } else { $vsInstances } + $vsVersion = $vsInstance.installationVersion + $vsPath = $vsInstance.installationPath + Write-Status "Visual Studio found: version $vsVersion" "Success" + Write-Status " Path: $vsPath" "Info" + $script:success += "Visual Studio detected (version $vsVersion)" + } +} else { + Write-Status "Visual Studio not found (vswhere.exe missing)" "Warning" + $script:warnings += "Could not detect Visual Studio installation" +} + +# Step 4: Check Git Submodules +Write-Status "Checking git submodules..." "Step" +$submodulesOk = Test-GitSubmodules +if ($submodulesOk) { + Write-Status "All required submodules present" "Success" +} else { + Write-Status "Some submodules are missing" "Error" + if ($FixIssues) { + Sync-GitSubmodules + } else { + Write-Status "Run with -FixIssues to automatically sync submodules" "Info" + } +} + +# Step 5: Check CMake Cache +Write-Status "Checking CMake cache..." "Step" +$cacheOk = Test-CMakeCache +if ($cacheOk) { + Write-Status "CMake cache is up to date" "Success" +} else { + if ($CleanCache -or $FixIssues) { + Clean-CMakeCache + } else { + Write-Status "Run with -CleanCache to remove old cache files" "Info" + } +} + +# Step 6: Check Dependencies +Test-DependencyCompatibility + +# Step 7: Test CMake Configuration (if requested) +if ($Verbose -or $FixIssues) { + Test-CMakeConfiguration +} + +# ============================================================================ +# Summary Report +# ============================================================================ + +$duration = (Get-Date) - $startTime + +Write-Host "`n╔════════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan +Write-Host "║ Verification Summary ║" -ForegroundColor Cyan +Write-Host "╚════════════════════════════════════════════════════════════════╝`n" -ForegroundColor Cyan + +Write-Host "Duration: $([math]::Round($duration.TotalSeconds, 2)) seconds`n" + +if ($script:success.Count -gt 0) { + Write-Host "✓ Successes ($($script:success.Count)):" -ForegroundColor Green + foreach ($item in $script:success) { + Write-Host " • $item" -ForegroundColor Green + } + Write-Host "" +} + +if ($script:warnings.Count -gt 0) { + Write-Host "⚠ Warnings ($($script:warnings.Count)):" -ForegroundColor Yellow + foreach ($item in $script:warnings) { + Write-Host " • $item" -ForegroundColor Yellow + } + Write-Host "" +} + +if ($script:issuesFound.Count -gt 0) { + Write-Host "✗ Issues Found ($($script:issuesFound.Count)):" -ForegroundColor Red + foreach ($item in $script:issuesFound) { + Write-Host " • $item" -ForegroundColor Red + } + Write-Host "" + + Write-Host "Recommended Actions:" -ForegroundColor Yellow + Write-Host " 1. Run: .\scripts\verify-build-environment.ps1 -FixIssues" -ForegroundColor Cyan + Write-Host " 2. Install missing dependencies" -ForegroundColor Cyan + Write-Host " 3. Check build instructions: docs/02-build-instructions.md" -ForegroundColor Cyan + Write-Host "" + + exit 1 +} else { + Write-Host "╔════════════════════════════════════════════════════════════════╗" -ForegroundColor Green + Write-Host "║ ✓ Build Environment Ready for Development! ║" -ForegroundColor Green + Write-Host "╚════════════════════════════════════════════════════════════════╝`n" -ForegroundColor Green + + Write-Host "Next Steps:" -ForegroundColor Cyan + Write-Host " Visual Studio CMake Workflow:" -ForegroundColor White + Write-Host " 1. Open Visual Studio 2022" -ForegroundColor Gray + Write-Host " 2. File → Open → Folder" -ForegroundColor Gray + Write-Host " 3. Select the yaze directory" -ForegroundColor Gray + Write-Host " 4. Visual Studio will detect CMakeLists.txt" -ForegroundColor Gray + Write-Host " 5. Select Debug/Release from toolbar" -ForegroundColor Gray + Write-Host " 6. Press F5 to build and run" -ForegroundColor Gray + Write-Host "" + Write-Host " Command Line (Alternative):" -ForegroundColor White + Write-Host " cmake -B build -DCMAKE_BUILD_TYPE=Debug" -ForegroundColor Gray + Write-Host " cmake --build build --config Debug" -ForegroundColor Gray + Write-Host "" + + exit 0 +} diff --git a/scripts/verify-build-environment.sh b/scripts/verify-build-environment.sh new file mode 100755 index 00000000..5abf1f4e --- /dev/null +++ b/scripts/verify-build-environment.sh @@ -0,0 +1,401 @@ +#!/bin/bash +# YAZE Build Environment Verification Script for macOS/Linux +# This script verifies the build environment is properly configured and ready to build + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +NC='\033[0m' # No Color + +VERBOSE=0 +FIX_ISSUES=0 +CLEAN_CACHE=0 + +issues_found=() +warnings=() +successes=() + +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + --verbose|-v) + VERBOSE=1 + shift + ;; + --fix|-f) + FIX_ISSUES=1 + shift + ;; + --clean|-c) + CLEAN_CACHE=1 + shift + ;; + --help|-h) + echo "Usage: $0 [OPTIONS]" + echo "" + echo "Options:" + echo " --verbose, -v Show detailed output" + echo " --fix, -f Automatically fix issues" + echo " --clean, -c Clean CMake cache" + echo " --help, -h Show this help message" + exit 0 + ;; + *) + echo "Unknown option: $1" + exit 1 + ;; + esac +done + +print_status() { + local type=$1 + local message=$2 + local timestamp=$(date +"%H:%M:%S") + + case $type in + success) + echo -e "[$timestamp] ${GREEN}✓${NC} $message" + ;; + error) + echo -e "[$timestamp] ${RED}✗${NC} $message" + ;; + warning) + echo -e "[$timestamp] ${YELLOW}⚠${NC} $message" + ;; + info) + echo -e "[$timestamp] ${CYAN}ℹ${NC} $message" + ;; + step) + echo "" + echo -e "[$timestamp] ${BLUE}▶${NC} ${BLUE}$message${NC}" + ;; + esac +} + +check_command() { + if command -v "$1" &> /dev/null; then + return 0 + else + return 1 + fi +} + +get_cmake_version() { + cmake --version 2>/dev/null | head -n1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown" +} + +check_git_submodules() { + local submodules=( + "src/lib/SDL" + "src/lib/abseil-cpp" + "src/lib/asar" + "src/lib/imgui" + "third_party/json" + "third_party/httplib" + ) + + local all_present=0 + local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + local root_dir="$(cd "$script_dir/.." && pwd)" + + for submodule in "${submodules[@]}"; do + if [ ! -d "$root_dir/$submodule" ] || [ -z "$(ls -A "$root_dir/$submodule")" ]; then + print_status error "Submodule missing or empty: $submodule" + issues_found+=("Missing submodule: $submodule") + all_present=1 + elif [ $VERBOSE -eq 1 ]; then + print_status success "Submodule found: $submodule" + fi + done + + return $all_present +} + +check_cmake_cache() { + local build_dirs=("build" "build_test" "build-grpc-test") + local cache_issues=0 + local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + local root_dir="$(cd "$script_dir/.." && pwd)" + + for dir in "${build_dirs[@]}"; do + local cache_path="$root_dir/$dir/CMakeCache.txt" + if [ -f "$cache_path" ]; then + local cache_age=$(($(date +%s) - $(stat -f %m "$cache_path" 2>/dev/null || stat -c %Y "$cache_path"))) + local cache_days=$((cache_age / 86400)) + + if [ $cache_days -gt 7 ]; then + print_status warning "CMake cache in '$dir' is $cache_days days old" + warnings+=("Old CMake cache in $dir (consider cleaning)") + cache_issues=1 + elif [ $VERBOSE -eq 1 ]; then + print_status success "CMake cache in '$dir' is recent" + fi + fi + done + + return $cache_issues +} + +check_dependency_compatibility() { + print_status step "Testing dependency configuration..." + + local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + local root_dir="$(cd "$script_dir/.." && pwd)" + + # Check gRPC configuration + local grpc_path="$root_dir/cmake/grpc.cmake" + if [ -f "$grpc_path" ]; then + if grep -q "CMAKE_DISABLE_FIND_PACKAGE_Protobuf TRUE" "$grpc_path"; then + print_status success "gRPC isolation configured correctly" + else + print_status warning "gRPC may conflict with system protobuf" + warnings+=("gRPC not properly isolated from system packages") + fi + fi + + # Check httplib + if [ -d "$root_dir/third_party/httplib" ]; then + print_status success "httplib found in third_party" + successes+=("httplib header-only library available") + fi + + # Check json library + if [ -d "$root_dir/third_party/json/include" ]; then + print_status success "nlohmann/json found in third_party" + successes+=("nlohmann/json header-only library available") + fi +} + +clean_cmake_cache() { + print_status step "Cleaning CMake cache..." + + local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + local root_dir="$(cd "$script_dir/.." && pwd)" + local build_dirs=("build" "build_test" "build-grpc-test") + + for dir in "${build_dirs[@]}"; do + if [ -d "$root_dir/$dir" ]; then + print_status info "Removing $dir..." + rm -rf "$root_dir/$dir" + fi + done + + print_status success "CMake cache cleaned" +} + +sync_git_submodules() { + print_status step "Syncing git submodules..." + + local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + local root_dir="$(cd "$script_dir/.." && pwd)" + + cd "$root_dir" + + print_status info "Running: git submodule sync --recursive" + git submodule sync --recursive + + print_status info "Running: git submodule update --init --recursive" + git submodule update --init --recursive + + print_status success "Submodules synced successfully" +} + +test_cmake_configuration() { + print_status step "Testing CMake configuration..." + + local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + local root_dir="$(cd "$script_dir/.." && pwd)" + local test_build_dir="$root_dir/build_test_config" + + print_status info "Configuring CMake (this may take a moment)..." + + if cmake -B "$test_build_dir" -S "$root_dir" \ + -DCMAKE_BUILD_TYPE=Debug \ + -DYAZE_MINIMAL_BUILD=ON \ + -DYAZE_BUILD_TESTS=OFF &>/dev/null; then + + print_status success "CMake configuration successful" + successes+=("CMake configuration test passed") + + # Cleanup test build + rm -rf "$test_build_dir" + return 0 + else + print_status error "CMake configuration failed" + issues_found+=("CMake configuration test failed") + return 1 + fi +} + +# ============================================================================ +# Main Verification Process +# ============================================================================ + +echo "" +echo -e "${CYAN}╔════════════════════════════════════════════════════════════════╗${NC}" +echo -e "${CYAN}║ YAZE Build Environment Verification (macOS/Linux) ║${NC}" +echo -e "${CYAN}╚════════════════════════════════════════════════════════════════╝${NC}" +echo "" + +start_time=$(date +%s) + +# Step 1: Check CMake +print_status step "Checking CMake installation..." +if check_command cmake; then + cmake_version=$(get_cmake_version) + print_status success "CMake found: version $cmake_version" + + # Check version + major=$(echo "$cmake_version" | cut -d. -f1) + minor=$(echo "$cmake_version" | cut -d. -f2) + + if [ "$major" -lt 3 ] || ([ "$major" -eq 3 ] && [ "$minor" -lt 16 ]); then + print_status error "CMake version too old (need 3.16+)" + issues_found+=("CMake version $cmake_version is below minimum 3.16") + fi +else + print_status error "CMake not found in PATH" + issues_found+=("CMake not installed or not in PATH") +fi + +# Step 2: Check Git +print_status step "Checking Git installation..." +if check_command git; then + git_version=$(git --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+') + print_status success "Git found: version $git_version" +else + print_status error "Git not found in PATH" + issues_found+=("Git not installed or not in PATH") +fi + +# Step 3: Check Platform-Specific Tools +print_status step "Checking platform-specific tools..." +if [[ "$OSTYPE" == "darwin"* ]]; then + if check_command xcodebuild; then + xcode_version=$(xcodebuild -version | head -n1) + print_status success "Xcode found: $xcode_version" + else + print_status warning "Xcode not found (optional but recommended)" + warnings+=("Xcode Command Line Tools not installed") + fi +elif [[ "$OSTYPE" == "linux-gnu"* ]]; then + if check_command gcc || check_command clang; then + print_status success "C++ compiler found" + else + print_status error "No C++ compiler found" + issues_found+=("Install build-essential or clang") + fi + + # Check for GTK (needed for NFD on Linux) + if pkg-config --exists gtk+-3.0; then + print_status success "GTK+3 found" + else + print_status warning "GTK+3 not found (needed for file dialogs)" + warnings+=("Install libgtk-3-dev for native file dialogs") + fi +fi + +# Step 4: Check Git Submodules +print_status step "Checking git submodules..." +if check_git_submodules; then + print_status success "All required submodules present" +else + print_status error "Some submodules are missing" + if [ $FIX_ISSUES -eq 1 ]; then + sync_git_submodules + else + print_status info "Run with --fix to automatically sync submodules" + fi +fi + +# Step 5: Check CMake Cache +print_status step "Checking CMake cache..." +if check_cmake_cache; then + print_status success "CMake cache is up to date" +else + if [ $CLEAN_CACHE -eq 1 ] || [ $FIX_ISSUES -eq 1 ]; then + clean_cmake_cache + else + print_status info "Run with --clean to remove old cache files" + fi +fi + +# Step 6: Check Dependencies +check_dependency_compatibility + +# Step 7: Test CMake Configuration (if requested) +if [ $VERBOSE -eq 1 ] || [ $FIX_ISSUES -eq 1 ]; then + test_cmake_configuration +fi + +# ============================================================================ +# Summary Report +# ============================================================================ + +end_time=$(date +%s) +duration=$((end_time - start_time)) + +echo "" +echo -e "${CYAN}╔════════════════════════════════════════════════════════════════╗${NC}" +echo -e "${CYAN}║ Verification Summary ║${NC}" +echo -e "${CYAN}╚════════════════════════════════════════════════════════════════╝${NC}" +echo "" + +echo "Duration: $duration seconds" +echo "" + +if [ ${#successes[@]} -gt 0 ]; then + echo -e "${GREEN}✓ Successes (${#successes[@]}):${NC}" + for item in "${successes[@]}"; do + echo -e " ${GREEN}•${NC} $item" + done + echo "" +fi + +if [ ${#warnings[@]} -gt 0 ]; then + echo -e "${YELLOW}⚠ Warnings (${#warnings[@]}):${NC}" + for item in "${warnings[@]}"; do + echo -e " ${YELLOW}•${NC} $item" + done + echo "" +fi + +if [ ${#issues_found[@]} -gt 0 ]; then + echo -e "${RED}✗ Issues Found (${#issues_found[@]}):${NC}" + for item in "${issues_found[@]}"; do + echo -e " ${RED}•${NC} $item" + done + echo "" + + echo -e "${YELLOW}Recommended Actions:${NC}" + echo -e " 1. Run: ${CYAN}./scripts/verify-build-environment.sh --fix${NC}" + echo -e " 2. Install missing dependencies" + echo -e " 3. Check build instructions: ${CYAN}docs/02-build-instructions.md${NC}" + echo "" + + exit 1 +else + echo -e "${GREEN}╔════════════════════════════════════════════════════════════════╗${NC}" + echo -e "${GREEN}║ ✓ Build Environment Ready for Development! ║${NC}" + echo -e "${GREEN}╚════════════════════════════════════════════════════════════════╝${NC}" + echo "" + + echo -e "${CYAN}Next Steps:${NC}" + if [[ "$OSTYPE" == "darwin"* ]]; then + echo -e " ${BLUE}macOS:${NC}" + echo " cmake --preset debug" + echo " cmake --build build" + else + echo -e " ${BLUE}Linux:${NC}" + echo " cmake -B build -DCMAKE_BUILD_TYPE=Debug" + echo " cmake --build build" + fi + echo "" + + exit 0 +fi