110 lines
7.4 KiB
PowerShell
110 lines
7.4 KiB
PowerShell
param(
|
|
[Parameter(Mandatory = $true)][string]$Rustc,
|
|
[Parameter(Mandatory = $true)][string]$IcedRlib,
|
|
[Parameter(Mandatory = $true)][string]$UnicodeSegmentationRlib,
|
|
[Parameter(Mandatory = $true)][string]$DependencyDirectory,
|
|
[Parameter(Mandatory = $true)][string]$Linker,
|
|
[Parameter(Mandatory = $true)][string]$NativeLibraryDirectory,
|
|
[Parameter(Mandatory = $true)][string]$NewRunDirectory
|
|
)
|
|
$ErrorActionPreference = 'Stop'
|
|
# Only the integration owner may invoke this while holding the compiler/GPU gate.
|
|
# No Cargo, dependency fetching, source mutation or existing output replacement.
|
|
$labelRustc = (Resolve-Path -LiteralPath $Rustc).Path
|
|
$labelIced = (Resolve-Path -LiteralPath $IcedRlib).Path
|
|
$labelUnicode = (Resolve-Path -LiteralPath $UnicodeSegmentationRlib).Path
|
|
$labelDeps = (Resolve-Path -LiteralPath $DependencyDirectory).Path
|
|
$labelLinker = (Resolve-Path -LiteralPath $Linker).Path
|
|
$labelNative = (Resolve-Path -LiteralPath $NativeLibraryDirectory).Path
|
|
$labelRun = [IO.Path]::GetFullPath($NewRunDirectory)
|
|
if (Test-Path -LiteralPath $labelRun) { throw 'Run directory already exists; preserve it and select a new path.' }
|
|
$labelMain = Join-Path $PSScriptRoot 'main.rs'
|
|
$labelModule = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '../../../crates/oa-desktop/src/behavior/scenario_label.rs'))
|
|
$labelScript = Join-Path $PSScriptRoot 'build-and-run.ps1'
|
|
New-Item -ItemType Directory -Path $labelRun | Out-Null
|
|
$labelExe = Join-Path $labelRun 'scenario-label-wgpu.exe'
|
|
$labelArguments = @(
|
|
'--edition=2024', '--crate-name', 'scenario_label_wgpu', '--crate-type', 'bin',
|
|
'-C', 'debuginfo=0', '-L', ('dependency=' + $labelDeps),
|
|
'-C', ('linker=' + $labelLinker), '-L', ('native=' + $labelNative),
|
|
'--extern', ('iced=' + $labelIced),
|
|
'--extern', ('unicode_segmentation=' + $labelUnicode),
|
|
$labelMain, '-o', $labelExe
|
|
)
|
|
$labelInputs = @($labelRustc, $labelLinker, $labelIced, $labelUnicode, $labelMain, $labelModule, $labelScript) | ForEach-Object {
|
|
$labelHash = Get-FileHash -LiteralPath $_ -Algorithm SHA256
|
|
[ordered]@{ path = $_; sha256 = $labelHash.Hash }
|
|
}
|
|
function Get-LabelArtifactManifest([string]$Directory, [switch]$AllFiles) {
|
|
Get-ChildItem -LiteralPath $Directory -File -Recurse | Where-Object {
|
|
$AllFiles -or $_.Extension -in @('.rlib', '.rmeta', '.dll', '.lib', '.a', '.o', '.obj')
|
|
} | Sort-Object FullName | ForEach-Object {
|
|
[ordered]@{
|
|
path = [IO.Path]::GetRelativePath($Directory, $_.FullName)
|
|
bytes = $_.Length
|
|
sha256 = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash
|
|
}
|
|
}
|
|
}
|
|
# Supersets of Rust link/metadata artifacts and all explicit native-dir inputs,
|
|
# not a claim that every inventoried artifact is actually linked.
|
|
$labelDependencyManifest = @(Get-LabelArtifactManifest $labelDeps)
|
|
$labelNativeManifest = @(Get-LabelArtifactManifest $labelNative -AllFiles)
|
|
if ($labelDependencyManifest.Count -eq 0 -or $labelNativeManifest.Count -eq 0) { throw 'Empty dependency or native-library directory.' }
|
|
ConvertTo-Json -InputObject $labelDependencyManifest -Depth 4 | Set-Content -LiteralPath (Join-Path $labelRun 'dependency-artifacts-before.json') -Encoding utf8
|
|
ConvertTo-Json -InputObject $labelNativeManifest -Depth 4 | Set-Content -LiteralPath (Join-Path $labelRun 'native-artifacts-before.json') -Encoding utf8
|
|
$labelRecord = [ordered]@{
|
|
scope = 'Standalone actual WGPU canvas label evaluator; not desktop Scene/native acceptance'
|
|
startedUtc = [DateTime]::UtcNow.ToString('o')
|
|
os = [Environment]::OSVersion.ToString()
|
|
rustc = (& $labelRustc --version --verbose | Out-String)
|
|
arguments = $labelArguments
|
|
inputs = $labelInputs
|
|
dependencyDirectory = $labelDeps
|
|
nativeLibraryDirectory = $labelNative
|
|
WGPU_BACKEND = $env:WGPU_BACKEND
|
|
WGPU_ADAPTER_NAME = $env:WGPU_ADAPTER_NAME
|
|
}
|
|
$labelRecord | ConvertTo-Json -Depth 6 | Set-Content -LiteralPath (Join-Path $labelRun 'inputs.json') -Encoding utf8
|
|
& $labelRustc @labelArguments 2>&1 | Tee-Object -FilePath (Join-Path $labelRun 'build.log')
|
|
$labelBuildExit = $LASTEXITCODE
|
|
$labelDependenciesAfter = @(Get-LabelArtifactManifest $labelDeps)
|
|
$labelNativeAfter = @(Get-LabelArtifactManifest $labelNative -AllFiles)
|
|
ConvertTo-Json -InputObject $labelDependenciesAfter -Depth 4 | Set-Content -LiteralPath (Join-Path $labelRun 'dependency-artifacts-after.json') -Encoding utf8
|
|
ConvertTo-Json -InputObject $labelNativeAfter -Depth 4 | Set-Content -LiteralPath (Join-Path $labelRun 'native-artifacts-after.json') -Encoding utf8
|
|
$labelDependenciesStable = (ConvertTo-Json -InputObject $labelDependencyManifest -Depth 4 -Compress) -ceq (ConvertTo-Json -InputObject $labelDependenciesAfter -Depth 4 -Compress)
|
|
$labelNativeStable = (ConvertTo-Json -InputObject $labelNativeManifest -Depth 4 -Compress) -ceq (ConvertTo-Json -InputObject $labelNativeAfter -Depth 4 -Compress)
|
|
[ordered]@{
|
|
exit = $labelBuildExit; dependencyManifestStable = $labelDependenciesStable
|
|
nativeManifestStable = $labelNativeStable; endedUtc = [DateTime]::UtcNow.ToString('o')
|
|
} | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $labelRun 'compile-receipt.json') -Encoding utf8
|
|
if ($labelBuildExit -ne 0) { throw "Compilation failed with exit $labelBuildExit; this run is nonacceptance." }
|
|
if (!$labelDependenciesStable -or !$labelNativeStable) { throw 'Dependency/native inputs changed during linking; preserve this run as nonacceptance.' }
|
|
foreach ($labelInput in $labelInputs) {
|
|
if ((Get-FileHash -LiteralPath $labelInput.path -Algorithm SHA256).Hash -ne $labelInput.sha256) {
|
|
throw ('Input changed during compilation: ' + $labelInput.path)
|
|
}
|
|
}
|
|
$labelExeHash = (Get-FileHash -LiteralPath $labelExe -Algorithm SHA256).Hash
|
|
$labelOutput = Join-Path $labelRun 'pixels'
|
|
# A single NEW process owns initialization, settled fonts, renderer and all cases.
|
|
& $labelExe $labelOutput 2>&1 | Tee-Object -FilePath (Join-Path $labelRun 'run.log')
|
|
$labelRunExit = $LASTEXITCODE
|
|
$labelExeAfterHash = (Get-FileHash -LiteralPath $labelExe -Algorithm SHA256).Hash
|
|
$labelReceipt = [ordered]@{
|
|
executable = $labelExe; sha256Before = $labelExeHash; sha256After = $labelExeAfterHash
|
|
binaryStable = ($labelExeHash -ceq $labelExeAfterHash); exit = $labelRunExit
|
|
endedUtc = [DateTime]::UtcNow.ToString('o')
|
|
interpretation = '0=32 valid probes without candidate findings; 2=padding/corridor finding; 3=invalid coverage/contract probe; other=infrastructure/panic'
|
|
}
|
|
$labelReceipt | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath (Join-Path $labelRun 'receipt.json') -Encoding utf8
|
|
# Capture all produced evidence, even for exit 2/3 or a missing summary. The
|
|
# manifest itself is excluded naturally because it does not exist until written.
|
|
$labelOutputManifest = @(Get-LabelArtifactManifest $labelRun -AllFiles)
|
|
ConvertTo-Json -InputObject $labelOutputManifest -Depth 4 | Set-Content -LiteralPath (Join-Path $labelRun 'output-artifacts.json') -Encoding utf8
|
|
if ($labelExeHash -cne $labelExeAfterHash) { throw 'Executable changed during execution; this run is nonacceptance.' }
|
|
$labelSummary = Join-Path $labelOutput 'summary.txt'
|
|
if (!(Test-Path -LiteralPath $labelSummary)) { throw 'No complete summary: infrastructure failure or panic, not acceptance.' }
|
|
if ((Get-Content -LiteralPath $labelSummary -Raw) -notmatch '(?m)^cases=32\r?$') { throw 'Expected exactly 32 completed cases.' }
|
|
if ($labelRunExit -ne 0) { throw "Evaluator exit $labelRunExit. Preserve metrics/images; diagnose before changing the candidate." }
|