diff --git a/.github/workflows/build-native-action.yml b/.github/workflows/build-native-action.yml index aefe1eed..acb671ea 100644 --- a/.github/workflows/build-native-action.yml +++ b/.github/workflows/build-native-action.yml @@ -263,7 +263,14 @@ jobs: build_windows: name: "Python Windows" - runs-on: windows-latest + # Pinned to windows-2022 deliberately. windows-latest has rolled to + # VS 18 / VS 2026, whose product graph only exposes Win11 SDK 26100 + # (Microsoft.VisualStudio.Component.Windows10SDK.19041 etc. are + # silently no-op'd by the VS Installer there). Win10 SDK 26100 uses + # SSE intrinsics in that v140 (which Python 3.10/3.11 + # PCbuild pin to) chokes on, breaking the build. windows-2022 still + # ships VS 2022 plus multiple older SDKs that pair cleanly with v140. + runs-on: windows-2022 strategy: fail-fast: false matrix: @@ -317,6 +324,11 @@ jobs: - name: Build Python with Relenv env: RELENV_NATIVE_PY_VERSION: 3.10.15 + # Pin MSBuild to the older Windows 10 SDK we just installed + # alongside v140; the newer 26100 SDK on windows-latest has + # SSE intrinsics in that break C compiles under the + # v140 toolset Python 3.10/3.11 PCbuild targets. + WindowsTargetPlatformVersion: "10.0.19041.0" run: | python -m relenv build --no-pretty --arch=${{ matrix.arch }} --python=${{ steps.python-version.outputs.version }} diff --git a/.github/workflows/verify-build-action.yml b/.github/workflows/verify-build-action.yml index 558ac7ff..df8c9552 100644 --- a/.github/workflows/verify-build-action.yml +++ b/.github/workflows/verify-build-action.yml @@ -212,7 +212,9 @@ jobs: test_windows: name: "Verify Windows" - runs-on: windows-latest + # Match the build runner (windows-2022) — see build-native-action.yml + # for why we don't use windows-latest. + runs-on: windows-2022 strategy: fail-fast: false diff --git a/relenv/_scripts/install_vc_build.ps1 b/relenv/_scripts/install_vc_build.ps1 index 5528ca7e..eb4256f2 100644 --- a/relenv/_scripts/install_vc_build.ps1 +++ b/relenv/_scripts/install_vc_build.ps1 @@ -109,6 +109,55 @@ Write-Host "Confirming Presence of Visual Studio Build Tools: " -NoNewline # We're only gonna look for msbuild.exe if ( Test-Path -Path $MSBUILD_BIN ) { Write-Result "Success" -ForegroundColor Green + + # MSBuild is present, but Python's PCbuild for 3.10/3.11 pins + # PlatformToolset to v140. Current windows-latest runners ship VS + # without v140 by default, so use the VS bootstrapper to add the + # component to the existing install. We don't trust the installer's + # exit code (it returns non-zero in a few benign cases) — instead + # verify the v140 platform-toolset targets file exists afterwards. + $V140_TARGETS = "${env:ProgramFiles(x86)}\MSBuild\Microsoft.Cpp\v4.0\V140" + Write-Host "Ensuring v140 toolset is installed: " -NoNewline + if ( Test-Path -Path $V140_TARGETS ) { + Write-Result "Already present" -ForegroundColor Green + } else { + Write-Host "" + $VS_BOOTSTRAPPER = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\setup.exe" + if ( -not (Test-Path -Path $VS_BOOTSTRAPPER) ) { + $VS_BOOTSTRAPPER = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vs_installer.exe" + } + if ( -not (Test-Path -Path $VS_BOOTSTRAPPER) ) { + Write-Host " VS bootstrapper not found under Microsoft Visual Studio\Installer" + exit 1 + } + # Pass the entire command line as a single string so the embedded + # quotes around --installPath survive Start-Process intact. Passing + # an array would let Start-Process drop the quotes and the + # bootstrapper would parse "C:\Program" as the installPath value. + # `setup.exe modify` does NOT accept --wait (verified against + # Visual Studio Installer 4.x — `Option 'wait' is unknown`). + # --quiet already runs synchronously, and Start-Process -Wait + # below ensures we don't return until the bootstrapper exits. + # Pair v140 with the Windows 10 SDK 19041 (the latest SDK known + # to compile cleanly against the v140 toolset and Python 3.10/3.11 + # PCbuild headers; newer SDKs put SSE intrinsics in + # that v140 chokes on with C2440). Windows81SDK is not present + # in the VS 2022+/VS 18 product graph and silently no-op'd here. + $installer_cmdline = 'modify --installPath "{0}" --add Microsoft.VisualStudio.Component.VC.140 --add Microsoft.VisualStudio.Component.Windows10SDK.19041 --quiet --norestart --nocache' -f $VS_INST_LOC + Write-Host " Running: $VS_BOOTSTRAPPER $installer_cmdline" + $proc = Start-Process ` + -FilePath $VS_BOOTSTRAPPER ` + -ArgumentList $installer_cmdline ` + -PassThru -Wait -NoNewWindow + Write-Host " bootstrapper exit code: $($proc.ExitCode)" + Write-Host "Verifying v140 toolset: " -NoNewline + if ( Test-Path -Path $V140_TARGETS ) { + Write-Result "Success" -ForegroundColor Green + } else { + Write-Result "Failed (v140 still not registered with MSBuild)" -ForegroundColor Red + exit 1 + } + } } else { Write-Result "Missing" -ForegroundColor Yellow diff --git a/relenv/pyversions.py b/relenv/pyversions.py index cd504f08..e8a2f99e 100644 --- a/relenv/pyversions.py +++ b/relenv/pyversions.py @@ -1418,6 +1418,7 @@ def main(args: argparse.Namespace) -> None: if args.update: python_versions(create=True) + sys.exit(0) if args.list: for version in python_versions(): print(version)