param( [switch]$NoRun ) # Ensure script runs from repo root (where this script lives) $root = Split-Path -Parent $MyInvocation.MyCommand.Path Set-Location $root Write-Host "Working directory: $PWD" # Require Visual Studio 18 (2026) function Find-VisualStudio { $vswherePaths = @() if ($env:ProgramFiles -ne $null) { $vswherePaths += Join-Path $env:ProgramFiles 'Microsoft Visual Studio\Installer\vswhere.exe' } if (${env:ProgramFiles(x86)} -ne $null) { $vswherePaths += Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe' } foreach ($p in $vswherePaths) { if (Test-Path $p) { return @{Tool=$p} } } return $null } function Get-VS18 { $fv = Find-VisualStudio $vswhere = $null if ($fv -and $fv.Tool) { $vswhere = $fv.Tool } if ($vswhere) { try { $inst18 = & $vswhere -version "[18.0,19.0)" -products * -requires Microsoft.Component.MSBuild -property installationPath 2>$null if ($inst18) { $candidate = 'Visual Studio 18 2026' $has = & cmake --help | Select-String -Pattern $candidate -SimpleMatch -Quiet if ($has) { $inst18Path = $inst18.Trim() $vcvars = Join-Path $inst18Path 'VC\\Auxiliary\\Build\\vcvarsall.bat' if (Test-Path $vcvars) { return @{Generator=$candidate; InstallPath=$inst18Path} } Write-Error "Visual Studio 18 detected at $inst18Path but C++ toolchain (vcvarsall.bat) is missing. Install the Desktop development with C++ workload." } } } catch { # fall through to path checks below } } # fallback: check common install locations (allow for non-standard drive) $commonPaths = @( 'D:\Program Files\Microsoft Visual Studio\2026\Community', 'D:\Program Files\Microsoft Visual Studio\2026\Professional', 'D:\Program Files\Microsoft Visual Studio\2026\Enterprise', 'C:\Program Files\Microsoft Visual Studio\2026\Community', 'C:\Program Files\Microsoft Visual Studio\2026\Professional', 'C:\Program Files\Microsoft Visual Studio\2026\Enterprise' ) foreach ($p in $commonPaths) { if (Test-Path $p) { $vcvars = Join-Path $p 'VC\\Auxiliary\\Build\\vcvarsall.bat' if (Test-Path $vcvars) { return @{Generator='Visual Studio 18 2026'; InstallPath=$p} } } } return $null } # Resolve vcpkg root/toolchain (prefer env, then C:\vcpkg, then repo-local) $vcpkgRoot = $env:VCPKG_ROOT if (-not $vcpkgRoot -or -not (Test-Path $vcpkgRoot)) { if (Test-Path 'C:\vcpkg') { $vcpkgRoot = 'C:\vcpkg' $env:VCPKG_ROOT = $vcpkgRoot } elseif (Test-Path (Join-Path $root 'vcpkg')) { $vcpkgRoot = Join-Path $root 'vcpkg' $env:VCPKG_ROOT = $vcpkgRoot } } $toolchainFile = $null if ($vcpkgRoot) { $candidateToolchain = Join-Path $vcpkgRoot 'scripts\buildsystems\vcpkg.cmake' if (Test-Path $candidateToolchain) { $toolchainFile = $candidateToolchain } } # Determine VS18 generator and reconfigure build-msvc if needed $preferred = Get-VS18 if ($preferred) { Write-Host "Detected Visual Studio: $($preferred.Generator) at $($preferred.InstallPath)" } else { Write-Error "Visual Studio 18 (2026) with Desktop development with C++ workload not found. Install VS 2026 and retry." exit 1 } if (-not $toolchainFile) { Write-Error "vcpkg toolchain not found. Set VCPKG_ROOT or install vcpkg (expected scripts/buildsystems/vcpkg.cmake)." exit 1 } # If build-msvc exists, check CMakeCache generator $cacheFile = Join-Path $root 'build-msvc\CMakeCache.txt' $reconfigured = $false if (-not (Test-Path $cacheFile)) { Write-Host "Configuring build-msvc with generator $($preferred.Generator) and vcpkg toolchain $toolchainFile" & cmake -S . -B build-msvc -G "$($preferred.Generator)" -A x64 -DCMAKE_TOOLCHAIN_FILE="$toolchainFile" -DVCPKG_TARGET_TRIPLET=x64-windows $cfgExit = $LASTEXITCODE if ($cfgExit -ne 0) { Write-Error "CMake configure failed with exit code $cfgExit"; exit $cfgExit } $reconfigured = $true } else { $genLine = Get-Content $cacheFile | Select-String -Pattern 'CMAKE_GENERATOR:INTERNAL=' -SimpleMatch $toolLine = Get-Content $cacheFile | Select-String -Pattern 'CMAKE_TOOLCHAIN_FILE:FILEPATH=' -SimpleMatch $currentGen = $null $currentTool = $null if ($genLine) { $currentGen = $genLine -replace '.*CMAKE_GENERATOR:INTERNAL=(.*)','$1' } if ($toolLine) { $currentTool = $toolLine -replace '.*CMAKE_TOOLCHAIN_FILE:FILEPATH=(.*)','$1' } $needsReconfigure = $false if ($currentGen -ne $preferred.Generator) { $needsReconfigure = $true } if (-not $currentTool -or ($currentTool -ne $toolchainFile)) { $needsReconfigure = $true } if ($needsReconfigure) { Write-Host "Generator or toolchain changed; cleaning build-msvc directory for fresh configure." Remove-Item -Path (Join-Path $root 'build-msvc') -Recurse -Force -ErrorAction SilentlyContinue Write-Host "Configuring build-msvc with generator $($preferred.Generator) and toolchain $toolchainFile" & cmake -S . -B build-msvc -G "$($preferred.Generator)" -A x64 -DCMAKE_TOOLCHAIN_FILE="$toolchainFile" -DVCPKG_TARGET_TRIPLET=x64-windows $cfgExit = $LASTEXITCODE if ($cfgExit -ne 0) { Write-Error "CMake configure failed with exit code $cfgExit"; exit $cfgExit } $reconfigured = $true } else { Write-Host "CMake cache matches required generator and toolchain." } } # Build Debug configuration Write-Host "Running: cmake --build build-msvc --config Debug" & cmake --build build-msvc --config Debug $buildExit = $LASTEXITCODE if ($buildExit -ne 0) { Write-Error "Build failed with exit code $buildExit" $vcpkgLog = Join-Path $root 'build-msvc\vcpkg-manifest-install.log' if (Test-Path $vcpkgLog) { $log = Get-Content $vcpkgLog -Raw if ($log -match 'Unable to find a valid Visual Studio instance') { Write-Error "vcpkg could not locate a valid Visual Studio 18 toolchain. Install VS 2026 with Desktop development with C++ workload and retry." } } exit $buildExit } if ($NoRun) { Write-Host "Build succeeded; skipping run because -NoRun was specified." exit 0 } $exePath = Join-Path $root "build-msvc\Debug\tetris.exe" if (-not (Test-Path $exePath)) { Write-Error "Executable not found: $exePath" exit 1 } Write-Host "Launching: $exePath" # Launch the executable and wait for it to exit so the caller sees its output. & $exePath exit $LASTEXITCODE