param( [string]$Compiler = 'clang', [string]$OutputDirectory = (Join-Path $PSScriptRoot '..\build\wasm-v23'), [switch]$Promote ) $ErrorActionPreference = 'Stop' $workspace = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot '..')).Path $output = [System.IO.Path]::GetFullPath($OutputDirectory) if (-not $output.StartsWith($workspace, [System.StringComparison]::OrdinalIgnoreCase)) { throw 'OutputDirectory must stay inside the workspace.' } $lock = Get-Content -LiteralPath (Join-Path $workspace 'toolchain.lock.json') -Raw -Encoding UTF8 | ConvertFrom-Json $versionLine = (& $Compiler --version | Select-Object -First 1) if ($versionLine -notmatch [regex]::Escape($lock.version)) { throw "Expected clang $($lock.version), got: $versionLine" } New-Item -ItemType Directory -Path $output -Force | Out-Null $common = @('--target=wasm32-unknown-unknown') + @($lock.commonFlags) $variants = @( [pscustomobject]@{ name='simd'; flags=@($lock.simdFlags) }, [pscustomobject]@{ name='scalar'; flags=@($lock.scalarFlags) } ) $modules = @( [pscustomobject]@{ symbol='WASM'; name='wasm'; source='shallow_kernel.c'; memory=2097152 }, [pscustomobject]@{ symbol='DEEP'; name='deep'; source='deep_kernel.c'; memory=8388608 }, [pscustomobject]@{ symbol='BLA'; name='bla'; source='bla_kernel_v18.c'; memory=33554432 }, [pscustomobject]@{ symbol='COLOR'; name='color'; source='color_kernel.c'; memory=2097152 } ) $payloads = @() foreach ($module in $modules) { foreach ($variant in $variants) { $file = "$($module.name)-$($variant.name).wasm" $path = Join-Path $output $file $args = $common + @($variant.flags) + @("-Wl,--initial-memory=$($module.memory)", "-Wl,--max-memory=$($module.memory)", '-o', $path, (Join-Path $workspace "src\$($module.source)") ) & $Compiler @args if ($LASTEXITCODE -ne 0) { throw "clang failed for $file" } $payloads += [ordered]@{ symbol = "$($module.symbol)_$($variant.name.ToUpperInvariant())_B64" file = $file bytes = (Get-Item -LiteralPath $path).Length sha256 = (Get-FileHash -LiteralPath $path -Algorithm SHA256).Hash.ToLowerInvariant() source = "src/$($module.source)" } } } $manifest = [ordered]@{ format = 'mandelbrot-source-wasm-manifest-v23' toolchain = $lock abi = 'src/abi.json' payloads = $payloads } $manifestPath = Join-Path $output 'manifest.json' $manifest | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $manifestPath -Encoding UTF8 if ($Promote) { & powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $workspace 'tests\kernel-golden.ps1') -GeneratedDirectory $output if ($LASTEXITCODE -ne 0) { throw 'Generated-WASM golden gate failed; payloads were not promoted.' } $generatedKernels = Join-Path $output 'kernels.js' & powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $workspace 'scripts\build-kernels.ps1') -ManifestPath $manifestPath -OutputPath $generatedKernels if ($LASTEXITCODE -ne 0) { throw 'kernels.js generation failed; payloads were not promoted.' } $dist = Join-Path $workspace 'dist\wasm' foreach ($payload in $payloads) { Copy-Item -LiteralPath (Join-Path $output $payload.file) -Destination (Join-Path $dist $payload.file) -Force } Copy-Item -LiteralPath $manifestPath -Destination (Join-Path $dist 'manifest.json') -Force Copy-Item -LiteralPath $generatedKernels -Destination (Join-Path $workspace 'kernels.js') -Force } Write-Output $manifestPath