What the gate checks today
scripts/unity/assert-msvc-toolchain.ps1 decides an IL2CPP host is usable when
cl.exe exists at the newest MSVC toolset path:
-ProbeExecutable { param($path) Test-Path -LiteralPath $path -PathType Leaf }
That is what #333 needed: the version directory was present, Unity discovered it
and put it on PATH, and cl.exe was absent — so the build died twenty minutes
later with a message naming neither the host nor the cause.
What it does not catch
A cl.exe that is present but cannot start — truncated by a failed update,
blocked by security tooling, missing a sibling DLL. The gate reports the host
healthy and the leg fails later, having already taken a Unity licence seat and
the organization build lock.
Why it was not simply added
A launch probe (cl.exe /?, treating any launch failure as unusable) has real
ways to fail on a healthy host:
cl.exe resolves sibling DLLs (mspdb*, msvcp*) from its own directory, and
the toolchain is normally invoked under vcvars;
- this gate runs before the organization build lock, so a false failure
blocks every IL2CPP leg on that runner, not just one job.
That is the same shape as the vswhere defect fixed in #331, where a discovery
failure was reported as a missing toolchain and would have told a healthy
runner's administrator to reinstall the C++ workload.
The asymmetry is what settled it for now: missing cl.exe is the failure that
actually happened and presence catches it; corrupt-but-present is rarer and still
fails the build, just later and more expensively.
What a fix needs
Not a blind change — a Windows host where both cases can be demonstrated:
- healthy toolchain: confirm the chosen probe exits 0 outside a
vcvars
environment, invoked by full path, as the gate would invoke it;
- corrupted toolchain (rename a sibling DLL, or truncate
cl.exe): confirm the
probe fails;
- add both to
scripts/__tests__/test-msvc-toolchain.ps1 via the existing
ProbeExecutable seam, which already makes the decision testable off Windows;
- keep the failure message distinguishing "no toolset", "compiler missing", and
"compiler present but unusable" — the operator fix differs for each.
If step 1 cannot be made reliable, the correct outcome is to close this and keep
the presence check, with the reasoning recorded.
Raised by GitHub Copilot on #331.
What the gate checks today
scripts/unity/assert-msvc-toolchain.ps1decides an IL2CPP host is usable whencl.exeexists at the newest MSVC toolset path:That is what #333 needed: the version directory was present, Unity discovered it
and put it on
PATH, andcl.exewas absent — so the build died twenty minuteslater with a message naming neither the host nor the cause.
What it does not catch
A
cl.exethat is present but cannot start — truncated by a failed update,blocked by security tooling, missing a sibling DLL. The gate reports the host
healthy and the leg fails later, having already taken a Unity licence seat and
the organization build lock.
Why it was not simply added
A launch probe (
cl.exe /?, treating any launch failure as unusable) has realways to fail on a healthy host:
cl.exeresolves sibling DLLs (mspdb*,msvcp*) from its own directory, andthe toolchain is normally invoked under
vcvars;blocks every IL2CPP leg on that runner, not just one job.
That is the same shape as the
vswheredefect fixed in #331, where a discoveryfailure was reported as a missing toolchain and would have told a healthy
runner's administrator to reinstall the C++ workload.
The asymmetry is what settled it for now: missing
cl.exeis the failure thatactually happened and presence catches it; corrupt-but-present is rarer and still
fails the build, just later and more expensively.
What a fix needs
Not a blind change — a Windows host where both cases can be demonstrated:
vcvarsenvironment, invoked by full path, as the gate would invoke it;
cl.exe): confirm theprobe fails;
scripts/__tests__/test-msvc-toolchain.ps1via the existingProbeExecutableseam, which already makes the decision testable off Windows;"compiler present but unusable" — the operator fix differs for each.
If step 1 cannot be made reliable, the correct outcome is to close this and keep
the presence check, with the reasoning recorded.
Raised by GitHub Copilot on #331.