[CmdletBinding()] param([string]$OutputName = 'VoxelForgeStandalone.exe') $ErrorActionPreference = 'Stop' $BuildHostProcess = Get-Process -Id $PID $BuildHostProcess.PriorityClass = 'BelowNormal' $BuildHostProcess.ProcessorAffinity = [IntPtr]0xFF00 $Root = [IO.Path]::GetFullPath($PSScriptRoot) $BuildDir = Join-Path $Root 'Build' $BinDir = Join-Path $Root 'bin' if ([IO.Path]::GetFileName($OutputName) -ne $OutputName -or [IO.Path]::GetExtension($OutputName) -ne '.exe') { throw "OutputName must be an executable filename, not a path: $OutputName" } $OutputPath = Join-Path $BinDir $OutputName [IO.Directory]::CreateDirectory($BuildDir) | Out-Null [IO.Directory]::CreateDirectory($BinDir) | Out-Null $VcVars = 'E:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat' if (-not (Test-Path -LiteralPath $VcVars -PathType Leaf)) { throw "MSVC environment script not found: $VcVars" } $Sources = @( (Join-Path $Root 'Source\StandaloneViewer.cpp'), (Join-Path $Root 'Compat\UnrealPerlin.cpp'), (Join-Path $Root 'Compat\StandaloneDataAssetGlue.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelBiomeDefinition.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelCaveMorphology.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelDensityAblation.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelDensityOpStack.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelDensityProfile.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelDiffLayer.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelGenerator.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelHeightOpStack.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelMarchingCubesMesher.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelSettings.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelStrateComposer.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelStrateManager.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelStrateMeasure.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelTerrainOpDefinition.cpp'), (Join-Path $Root 'Source\VoxelForge\Private\VoxelWormField.cpp') ) foreach ($Source in $Sources) { if (-not (Test-Path -LiteralPath $Source -PathType Leaf)) { throw "Required source is missing: $Source" } } $ResponsePath = Join-Path $BuildDir 'standalone.rsp' $RspLines = @( '/nologo', '/std:c++20', '/O2', '/arch:AVX2', '/fp:precise', '/EHsc', '/D_CRT_SECURE_NO_WARNINGS', ('/I"{0}"' -f (Join-Path $Root 'Compat')), ('/I"{0}"' -f (Join-Path $Root 'Source')), ('/I"{0}"' -f (Join-Path $Root 'Source\VoxelForge\Public')), ('/I"{0}"' -f (Join-Path $Root 'Source\VoxelForge\Private')), ('/Fe"{0}"' -f $OutputPath) ) # This build stays serial (no /MP); the daytime ceiling is four compiler processes. foreach ($Source in $Sources) { $RspLines += ('"{0}"' -f $Source) } $RspLines += @('/link','d3d11.lib','dxgi.lib','d3dcompiler.lib','user32.lib','gdi32.lib') [IO.File]::WriteAllLines($ResponsePath,$RspLines,[Text.UTF8Encoding]::new($false)) Push-Location $BuildDir try { # This PowerShell process already runs BelowNormal with affinity 0xFF00; # compile directly so cmd returns cl.exe's real exit code. $CommandLine = 'call "{0}" >nul && cl.exe @"{1}"' -f $VcVars,$ResponsePath & $env:ComSpec /d /s /c $CommandLine if ($LASTEXITCODE -ne 0) { throw "Standalone MSVC build failed with exit code $LASTEXITCODE" } if (-not (Test-Path -LiteralPath $OutputPath -PathType Leaf)) { throw "Standalone MSVC build reported success but did not produce: $OutputPath" } } finally { Pop-Location } Write-Host "Built $OutputPath"