diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 412ab511..bb49d6d8 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -786,39 +786,38 @@ jobs: emit linux ubuntu-latest linux-x86_64 tar.gz bin/mcpp registry/bin/xlings default "$ln" emit linux ubuntu-latest linux-x86_64 tar.gz bin/mcpp registry/bin/xlings llvm "$lln" emit macos macos-15 macosx-arm64 tar.gz bin/mcpp registry/bin/xlings default "$mn" - # WINDOWS IS PINNED, like macOS above, and for a reason that cost - # a day to find. `windows-latest` rolled to the Visual Studio 18 - # image (MSVC STL 14.51), and mcpp builds windows with clang - # targeting x86_64-pc-windows-msvc -- so every package here - # compiles against an STL written for a different front end. + # WINDOWS IS PINNED, like macOS above. `windows-latest` rolled to + # the Visual Studio 2026 image and took two separate things with + # it, which is why the first attempt at this pin was wrong. # - # Most survive that. `huxerui.huxerui` did not: + # THE TWO AXES. mcpp builds windows with clang targeting + # x86_64-pc-windows-msvc, so a windows job depends on the image for + # two unrelated things: # - # xutility:320: error: static assertion failed: unexpected size - # in instantiation of 'std::_Find_vectorized< - # const huxerui::detail::NodeExtensionHandle, ...>' + # * the Vulkan LOADER. `vulkan-1.dll` is not a Windows component + # -- it arrives with a GPU driver or the SDK -- so `vulkan`, + # `eui-neo-vulkan` and `vulkan-hpp-module` load it or fail at + # 0xC0000135. Measured: present on 2025 and on latest, ABSENT + # on 2022. + # * the MSVC STL clang compiles against. 14.51 rejects + # `huxerui.huxerui`: clang instantiates the vectorized + # `std::find` for a 24-byte type and hits + # `static_assert(false, "unexpected size")` in + # (mcpp-community/mcpp#609). # - # MSVC STL's vectorized `std::find` is guarded by a trait that - # decides whether the element type can be compared bitwise. - # `NodeExtensionHandle` is 24 bytes with no padding, trivially - # copyable, `operator==` defaulted -- the guard admits it under - # clang, and the helper it dispatches to implements 1/2/4/8-byte - # elements and static_asserts on the rest. Guard and implementation - # disagree about what "vectorizable" means, and only clang is there - # to notice. + # Pinning to `windows-2022` answered the second and broke the + # first -- a trade, not a fix. The two axes were assumed to move + # together because both were read off the image label. They do not. # - # NOT this index's bug, and not the package's: the same source, the - # same clang, compiles on the 2022 image's STL. Upstream HuxerUI's - # own mcpp CI is green for exactly that reason -- it pins - # `windows-2022`. Reported as mcpp-community/mcpp#609 so the pin can - # be lifted when the toolchain combination works. - # - # 13 of the 14 members on the shard that failed were unaffected, so - # this is not a blanket breakage -- which is precisely why a rolling - # label is the wrong thing to stand on: the next image moves the set - # of packages that happen to trip it, and the failure arrives - # attributed to whatever descriptor changed that week. - emit windows windows-2022 windows-x86_64 zip bin/mcpp.exe registry/bin/xlings.exe default "$wn" + # The 2025 image carries THREE toolsets -- 14.29.30133, 14.44.35207 + # and 14.51.36231 -- and the newest is the broken one. The step + # below moves 14.51 aside so the machine presents 14.44 as newest, + # which gets a new image (loader present) with an old STL (huxerui + # compiles). Setting `VCToolsInstallDir` was tried first and steers + # only clang's header search; mcpp picks `std.ixx` through its own + # SYSTEM detection and the two then disagreed. The step's own + # comment carries that. + emit windows windows-2025 windows-x86_64 zip bin/mcpp.exe registry/bin/xlings.exe default "$wn" printf ']}' } | sed 's/,]}/]}/' > /tmp/matrix.json echo "matrix=$(cat /tmp/matrix.json)" >> "$GITHUB_OUTPUT" @@ -1002,6 +1001,75 @@ jobs: key: mcpp-toolstore-${{ runner.os }}-${{ matrix.toolchain }}-${{ env.MCPP_VERSION }}-${{ github.run_id }}-${{ matrix.platform }}-${{ matrix.shard }} restore-keys: | mcpp-toolstore-${{ runner.os }}-${{ matrix.toolchain }}-${{ env.MCPP_VERSION }}- + - name: Take MSVC 14.51 out of view + if: runner.os == 'Windows' + shell: pwsh + # The 2025 image ships 14.29.30133, 14.44.35207 AND 14.51.36231, and + # 14.51 is the one clang cannot compile: it instantiates MSVC STL's + # vectorized `std::find` for any type its `__is_trivially_equality_ + # comparable` admits, then static_asserts on sizes other than 1/2/4/8 + # (microsoft/STL#6294, tracked for us as mcpp-community/mcpp#609). + # + # MOVING THE DIRECTORY, not setting VCToolsInstallDir, and the first + # attempt is why. That variable steers clang's header search and + # nothing else: mcpp finds MSVC STL's `std.ixx` through its own SYSTEM + # detection, which takes the NEWEST toolset on the machine. The two + # then disagreed -- 14.51's std.ixx compiled against 14.44's headers -- + # and every member using `import std` died on + # `std.ixx:126: fatal error: 'flat_map' file not found`. All five + # windows shards, where before only huxerui failed. + # + # mcpp says which lever is the right one: for the SYSTEM origin, + # "everything about which toolset this picks is a property of the + # machine, not of the caller" (src/toolchain/msvc.cppm). So change the + # machine. With 14.51 moved OUT of that directory, mcpp's detection + # and clang's own both land on 14.44 and cannot disagree. + # + # Ephemeral runner, ephemeral change. `msvc@` in a manifest is + # the per-package way to pin, but this has to hold for every member on + # the leg, and no member should have to know about a broken STL. + run: | + $vs = "C:\Program Files\Microsoft Visual Studio\18\Enterprise\VC\Tools\MSVC" + $bad = Join-Path $vs "14.51.36231" + $want = Join-Path $vs "14.44.35207" + if (-not (Test-Path $want)) { + Get-ChildItem $vs -Directory -EA SilentlyContinue | ForEach-Object { Write-Host " present: $($_.Name)" } + throw "MSVC 14.44.35207 is not on this image; see the emit-windows comment before changing the pin" + } + if (Test-Path $bad) { + # OUT of VC\Tools\MSVC, not renamed inside it. Renaming in + # place was tried and does not hide anything: mcpp enumerates + # every child of that directory, so + # `14.51.36231.disabled-see-mcpp-609` was still found -- and + # still sorted last, so still chosen. The log named it: + # `...\14.51.36231.disabled-see-mcpp-609\modules\std.ixx`. + $park = Join-Path $env:RUNNER_TEMP "msvc-14.51-parked" + Move-Item -Path $bad -Destination $park -Force + Write-Host "moved 14.51.36231 out to $park" + } else { + Write-Host "14.51.36231 not present; nothing to move" + } + # BOTH LEVERS, because they answer different consumers and each + # alone was measured failing: + # + # * moving 14.51 out settles mcpp, which SCANS the directory and + # takes the newest. Alone, it broke clang: clang's own MSVC + # detection goes through the VS installation's registration, + # which still names 14.51, so it found nothing and emitted a + # compile with NO include paths at all -- + # `std.ixx:12: fatal error: 'assert.h' file not found`, the UCRT + # header, from a command line carrying neither /imsvc nor -I. + # * `VCToolsInstallDir` settles clang, which reads it instead of + # detecting. Alone, it left mcpp scanning and picking 14.51, so + # 14.51's std.ixx compiled against 14.44's headers -- + # `std.ixx:126: fatal error: 'flat_map' file not found`. + # + # Neither consumer reads the other's answer. Setting both is not + # belt-and-braces; it is one answer per consumer. + "VCToolsInstallDir=$want\" | Out-File -Append -Encoding utf8 $env:GITHUB_ENV + Write-Host "VCToolsInstallDir -> $want" + Write-Host "visible toolsets now:" + Get-ChildItem $vs -Directory | ForEach-Object { Write-Host " $($_.Name)" } - name: Download mcpp shell: bash env: