[CmdletBinding()] param( [string]$OutputName = 'VoxelForgeCoreStandalone.exe', [ValidateSet('All','Core')][string]$Target = 'All' ) $ErrorActionPreference = 'Stop' $BuildHostProcess = Get-Process -Id $PID $BuildHostProcess.PriorityClass = 'BelowNormal' $BuildHostProcess.ProcessorAffinity = [IntPtr]0xFF00 $Root = [IO.Path]::GetFullPath($PSScriptRoot) $BuildDir = Join-Path $Root 'Build\VoxelForgeCore' $BinDir = Join-Path $Root 'bin' [IO.Directory]::CreateDirectory($BuildDir) | Out-Null [IO.Directory]::CreateDirectory($BinDir) | Out-Null if ($Target -eq 'All' -and ([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 $CoreLibrary = Join-Path $BuildDir 'VoxelForgeCore.lib' $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" } $SourceManifest = Join-Path $Root 'Core\core_sources.txt' if (-not (Test-Path -LiteralPath $SourceManifest -PathType Leaf)) { throw "Core source manifest not found: $SourceManifest" } $CoreSourceNames = @(Get-Content -LiteralPath $SourceManifest | ForEach-Object { $_.Trim() } | Where-Object { $_ -and -not $_.StartsWith('#') }) if ($CoreSourceNames.Count -eq 0) { throw "Core source manifest is empty: $SourceManifest" } $CoreSources = @($CoreSourceNames | ForEach-Object { $SourcePath = [IO.Path]::GetFullPath((Join-Path $Root $_)) if (-not $SourcePath.StartsWith($Root,[StringComparison]::OrdinalIgnoreCase)) { throw "Core source path escapes Standalone: $_" } $SourcePath }) foreach ($Source in $CoreSources) { if (-not (Test-Path -LiteralPath $Source -PathType Leaf)) { throw "Required core source is missing: $Source" } } $IncludeArgs = @( ('/I"{0}"' -f (Join-Path $Root 'Core\include')), ('/I"{0}"' -f (Join-Path $Root 'Core\src')), ('/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')) ) $CommonFlags = @('/nologo','/std:c++20','/O2','/arch:AVX2','/fp:precise','/EHsc','/MP8','/D_CRT_SECURE_NO_WARNINGS') + $IncludeArgs $CoreRsp = Join-Path $BuildDir 'core-compile.rsp' $CoreRspLines = $CommonFlags + @('/c') + @($CoreSources | ForEach-Object { '"{0}"' -f $_ }) [IO.File]::WriteAllLines($CoreRsp,$CoreRspLines,[Text.UTF8Encoding]::new($false)) $Objects = @($CoreSources | ForEach-Object { '"{0}.obj"' -f [IO.Path]::GetFileNameWithoutExtension($_) }) $LibRsp = Join-Path $BuildDir 'core-library.rsp' [IO.File]::WriteAllLines($LibRsp,@('/nologo',('/OUT:"{0}"' -f $CoreLibrary)) + $Objects,[Text.UTF8Encoding]::new($false)) $ViewerRsp = Join-Path $BuildDir 'viewer-link.rsp' $ViewerRspLines = $CommonFlags + @( ('/Fe"{0}"' -f $OutputPath), ('"{0}"' -f (Join-Path $Root 'Source\StandaloneViewer.cpp')), ('"{0}"' -f $CoreLibrary), '/link','d3d11.lib','dxgi.lib','d3dcompiler.lib','user32.lib','gdi32.lib' ) [IO.File]::WriteAllLines($ViewerRsp,$ViewerRspLines,[Text.UTF8Encoding]::new($false)) Push-Location $BuildDir try { # One cl process with /MP8 bounds compiler work to eight processes; MSVC, lib.exe, and the # viewer link inherit BelowNormal priority and the 0xFF00 process affinity from this host. $CommandLine = 'call "{0}" >nul && cl.exe @"{1}" && lib.exe @"{2}"' -f $VcVars,$CoreRsp,$LibRsp if ($Target -eq 'All') { $CommandLine += ' && cl.exe @"{0}"' -f $ViewerRsp } & $env:ComSpec /d /s /c $CommandLine if ($LASTEXITCODE -eq -1073741502) { throw 'A build process exited with 0xC0000142; stopping as required.' } if ($LASTEXITCODE -ne 0) { throw "VoxelForgeCore build failed with exit code $LASTEXITCODE" } if (-not (Test-Path -LiteralPath $CoreLibrary -PathType Leaf)) { throw "Core library was not produced: $CoreLibrary" } if ($Target -eq 'All' -and -not (Test-Path -LiteralPath $OutputPath -PathType Leaf)) { throw "Viewer was not produced: $OutputPath" } } finally { Pop-Location } Write-Host "Built $CoreLibrary" if ($Target -eq 'All') { Write-Host "Built $OutputPath" }