Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
894d9d5
ci(windows): use preinstalled MSYS2 + pacman-installed clang
Fedr Apr 30, 2026
84e190a
Merge remote-tracking branch 'origin/master' into ci/use-runner-msys2
Fedr Apr 30, 2026
4af6573
ci(windows): also install mingw-w64-clang-x86_64-llvm package
Fedr Apr 30, 2026
1f98820
Update mrbind.
adalisk-emikhaylov May 5, 2026
165d2c2
Generate fresh MSYS2 lockfiles.
adalisk-emikhaylov May 5, 2026
193e3e1
We no longer upload zipped MSYS2 to S3.
adalisk-emikhaylov May 5, 2026
bf25ec1
Merge branch 'master' into ci/use-runner-msys2
Fedr May 5, 2026
5a6fabf
ci(windows): make generate_win.bat fail loudly on missing MSYS2
Fedr May 5, 2026
d38cd0b
Try enabling the debug env.
adalisk-emikhaylov May 6, 2026
8070543
Hopefully fix ambiguous Python names.
adalisk-emikhaylov May 6, 2026
a1d3c5e
ci(windows): diagnostic step for embedded-python ImportError
Fedr May 7, 2026
9fbdfa5
ci(windows): pin MRBind clang stack to 18.1.8-2 via MSYS2 archive
Fedr May 7, 2026
c51ac82
ci(windows): pass --assume-installed cc-libs through pacman -U
Fedr May 7, 2026
2d2627d
ci(windows): keep libc++/libunwind at current; pin only clang/llvm/lld
Fedr May 7, 2026
ff8bcd8
ci(windows): pin the entire clang64 toolchain to clang-18 era
Fedr May 7, 2026
2722e7c
Revert thirdparty/mrbind submodule to the pre-PR baseline
Fedr May 7, 2026
a214242
ci(windows): replace inline pwsh download loop with the existing scripts
Fedr May 8, 2026
1c49411
ci(windows): pass -here to msys2_shell.cmd so script paths resolve
Fedr May 8, 2026
8b629c0
ci(windows): strip CR from msys2 lockfile before sha256sum -c
Fedr May 8, 2026
cff4999
Merge branch 'master' into ci/use-runner-msys2-pin-clang18
Fedr May 8, 2026
c018dcb
Merge branch 'master' into ci/use-runner-msys2-pin-clang18
Fedr May 8, 2026
eab4b16
ci(windows): route MB_PB11_ADJUST_NAMES via -include header instead o…
Fedr May 8, 2026
f386d46
ci(windows): bake MB_PB11_ADJUST_NAMES into the PCH source instead of…
Fedr May 8, 2026
7715fa7
ci(windows): skip mrbind_pb11_defines.h include during parser pass
Fedr May 8, 2026
642badd
ci(windows): scope mrbind_pb11_defines.h include to Python target only
Fedr May 8, 2026
5ab65f3
ci(windows): cache pinned MSYS2 packages and drop pacman -Sy
Fedr May 8, 2026
2224865
Merge branch 'master' into ci/use-runner-msys2-pin-clang18
Fedr May 8, 2026
e15694f
ci(windows): make cache-hit path skip wget HEAD requests
Fedr May 8, 2026
c6d8512
ci(windows): correct comments — root cause is clang, not bash/make
Fedr May 9, 2026
7f51350
ci(windows): re-correct comments — MSYS2 environment is the trigger
Fedr May 9, 2026
95cef36
ci(probe): instrument MB_PB11_ADJUST_NAMES PCH ↔ fragment asymmetry
Fedr May 9, 2026
988eedb
ci(probe): drop bash $SHELL shim, keep only clang++ argv shim
Fedr May 9, 2026
7a54c83
ci(probe): fix tool-version dump to capture make + binary paths
Fedr May 9, 2026
4555d25
ci(probe): move tool-version dump to a shell script
Fedr May 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions .github/actions/install-msys2-mrbind/action.yml

This file was deleted.

211 changes: 207 additions & 4 deletions .github/workflows/build-test-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,23 +138,67 @@ jobs:
with:
dotnet-version: '8.0.x'

- name: Install MSYS2 for MRBind
- name: Cache pinned MSYS2 packages
# Avoid re-downloading the ~700 MB of 47 .pkg.tar.zst files on every
# run. Cache key tracks the lockfile so any URL/hash bump invalidates.
# The download script uses `wget -nc`, so a cache hit lets it skip
# every file without contacting the server; the install script's
# sha256 verify is the safety net.
if: ${{inputs.mrbind || (inputs.mrbind_c && matrix.build_system == 'CMake') || env.BUILD_C_SHARP == 'true'}}
uses: ./.github/actions/install-msys2-mrbind
uses: actions/cache@v5
with:
path: scripts/mrbind/msys2_packages
key: msys2-mrbind-clang18-${{ hashFiles('scripts/mrbind/msys2_package_hashes_clang18.txt') }}

- name: Install MRBind toolchain (clang 18.1.8 pinned) into runner MSYS2
# mrbind's bindings regressed when generated with clang >= ~22 (lost
# the std_vector_const_Mesh registration; surfaces as
# `ImportError: initialization failed` from MRTest's embedded-python
# smoke test). Pin the WHOLE mingw/clang64 toolchain to the era of
# clang 18.1.8-2 — the version the historical
# msys64_meshlib_mrbind.zip bundle shipped, with matching
# crt-git/headers-git/libwinpthread-git/libc++/cmake/ninja from
# late 2024.
#
# Pinning only the clang/llvm packages doesn't work: clang 18's
# cc.exe fails to load (STATUS_DLL_NOT_FOUND, exit 127) when the
# rest of the runtime is at current versions. The pinned URL list
# is in scripts/mrbind/msys2_package_urls_clang18.txt with
# corresponding sha256s in msys2_package_hashes_clang18.txt — bump
# both when MeshLib is ready to move off clang 18.
if: ${{inputs.mrbind || (inputs.mrbind_c && matrix.build_system == 'CMake') || env.BUILD_C_SHARP == 'true'}}
shell: pwsh
run: |
# Download the pinned 18-era set (47 packages) and pacman -U the
# whole thing in one transaction so dep resolution is internally
# consistent — none of these packages knows about the newer
# cc-libs marker, and all transitively pinned to matching
# libwinpthread-git/crt-git/headers-git revisions, so there are
# no version skews. The install script verifies sha256s before
# invoking pacman. `-here` keeps the workflow's checkout dir as
# the shell's cwd so the relative `scripts/mrbind/...` paths
# resolve. We don't `pacman -Sy` first: `pacman -U` operates on
# local files and only needs the runner's preinstalled DB to
# exist (it does, even unsynced).
C:\msys64\msys2_shell.cmd -no-start -defterm -here -c "set -e && bash scripts/mrbind/msys2_download_packages.sh _clang18 && bash scripts/mrbind/msys2_install_packages.sh _clang18"

- name: Install gettext utilities
if: ${{ inputs.upload_artifacts }}
run: |
C:\msys64_meshlib_mrbind\msys2_shell.cmd -clang64 -defterm -no-start -c "pacman -S --noconfirm --needed mingw-w64-clang-x86_64-gettext-tools"
C:\msys64\msys2_shell.cmd -clang64 -defterm -no-start -c "pacman -S --noconfirm --needed mingw-w64-clang-x86_64-gettext-tools"

- name: Build MRBind
if: ${{inputs.mrbind || (inputs.mrbind_c && matrix.build_system == 'CMake') || env.BUILD_C_SHARP == 'true'}}
shell: cmd
env:
MSYS2_DIR: C:\msys64
run: call ./scripts/mrbind/install_mrbind_windows_msys2.bat

- name: Generate C bindings
if: ${{ (inputs.mrbind_c && matrix.build_system == 'CMake') || env.BUILD_C_SHARP == 'true' }}
shell: cmd
env:
MSYS2_DIR: C:\msys64
# Note that `\` doesn't work here as a line continuation, and will lead to weird errors.
run: |
call "${{matrix.vc-path}}\Common7\Tools\VsDevCmd.bat" -arch=amd64 ${{ fromJSON('["", "-vcvars_ver=14.2"]')[matrix.cxx_compiler == 'msvc-2019'] }}
Expand All @@ -164,6 +208,8 @@ jobs:
- name: Generate C# bindings
if: ${{ env.BUILD_C_SHARP == 'true' }}
shell: cmd
env:
MSYS2_DIR: C:\msys64
# Note that `\` doesn't work here as a line continuation, and will lead to weird errors.
run: |
call "${{matrix.vc-path}}\Common7\Tools\VsDevCmd.bat" -arch=amd64 ${{ fromJSON('["", "-vcvars_ver=14.2"]')[matrix.cxx_compiler == 'msvc-2019'] }}
Expand All @@ -173,7 +219,7 @@ jobs:
- name: Build
shell: cmd
env:
GETTEXT_ROOT: C:\msys64_meshlib_mrbind\clang64
GETTEXT_ROOT: C:\msys64\clang64
VCPKG_ROOT: C:\vcpkg
VCPKG_TARGET_TRIPLET: ${{ matrix.vcpkg_triplet }}
# `|| exit /b 1` is used instead of `if errorlevel 1 exit 1`
Expand All @@ -191,9 +237,71 @@ jobs:
msbuild -m source\MeshLib.sln -p:Configuration=${{ matrix.config }} -p:VcpkgTriplet=%VCPKG_TARGET_TRIPLET%${{ fromJSON('["", ";PlatformToolset=v142"]')[matrix.cxx_compiler == 'msvc-2019'] }} || exit /b 1
)

- name: PROBE — install clang++ argv-logging shim
if: ${{inputs.mrbind && matrix.vcpkg_triplet != 'x64-windows-meshlib-iterator-debug'}}
shell: pwsh
run: |
$diagBin = 'C:\diag\bin'
New-Item -ItemType Directory -Force -Path $diagBin, C:\diag | Out-Null
# Install the shim under the name `clang++` so PATH lookup picks it up.
Copy-Item -Force scripts\diag\clang-argv-shim.sh "$diagBin\clang++"
# Strip CRLF the shim file may have been checked out with (shebang
# parsing fails on `#!/bin/bash<CR>`), and `chmod +x`.
C:\msys64\msys2_shell.cmd -no-start -defterm -here -c "set -e && tr -d '\r' < /c/diag/bin/clang++ > /tmp/shim && mv /tmp/shim /c/diag/bin/clang++ && chmod +x /c/diag/bin/clang++ && head -1 /c/diag/bin/clang++ && ls -la /c/diag/bin/"

- name: PROBE — Generate Python bindings under clang shim (expected to FAIL with macro mismatch)
if: ${{inputs.mrbind && matrix.vcpkg_triplet != 'x64-windows-meshlib-iterator-debug'}}
shell: cmd
env:
MSYS2_DIR: C:\msys64
continue-on-error: true
# We bypass generate_win.bat so we can inject `/c/diag/bin` first on
# PATH — make's recipes invoke `clang++` which then resolves to our
# shim, which logs argv (text + hex) before exec'ing the real
# `/c/msys64/clang64/bin/clang++.exe`.
run: |
call "${{matrix.vc-path}}\Common7\Tools\VsDevCmd.bat" -arch=amd64 ${{ fromJSON('["", "-vcvars_ver=14.2"]')[matrix.cxx_compiler == 'msvc-2019'] }}
call C:\msys64\msys2_shell.cmd -no-start -defterm -full-path -here -clang64 -c "export PATH=/c/diag/bin:$PATH && which clang++ && time make -f scripts/mrbind/generate.mk MODE=none -B --trace VS_MODE=${{matrix.config}}"

- name: PROBE — dump tool versions and clang argv log
if: ${{ inputs.mrbind && matrix.vcpkg_triplet != 'x64-windows-meshlib-iterator-debug' && always() }}
shell: pwsh
run: |
Write-Host "================ Tool versions ================"
# Use -full-path so Windows-side tools (Strawberry Perl's gmake,
# chocolatey's make, etc.) are also resolvable — same setup as
# the actual mrbind build. Inline bash got mangled by PowerShell
# escaping last attempt, so dispatch to a checked-in script.
C:\msys64\msys2_shell.cmd -no-start -defterm -full-path -here -clang64 -c "tr -d '\r' < scripts/diag/dump-toolchain-versions.sh > /tmp/dump.sh && bash /tmp/dump.sh"

$log = 'C:\diag\clang-argv.log'
Write-Host ""
Write-Host "================ clang argv log: $log ================"
if (-not (Test-Path $log)) {
Write-Host " (not produced — shim never invoked)"
return
}
Write-Host "Size: $((Get-Item $log).Length) bytes"
Write-Host ""
Write-Host "---- INVOCATIONS that mention MB_PB11_ADJUST_NAMES ----"
$content = Get-Content $log -Raw
$blocks = $content -split '====\r?\n'
foreach ($b in $blocks) {
if (-not ($b -match 'MB_PB11_ADJUST_NAMES')) { continue }
# Filter to compilations of interest (PCH source, fragments, aliases, helpers).
if (-not ($b -match 'combined_pch\.hpp|combined\.hpp|fragment\.[0-9]+\.o|aliases\.cpp|extra\.helpers')) { continue }
Write-Host "===="
# Print INVOCATION header + every MB_PB11_ADJUST_NAMES line + every compile-target identifier.
$b -split "`n" | Where-Object {
$_ -match 'INVOCATION|MB_PB11_ADJUST_NAMES|combined_pch\.hpp|combined\.hpp|fragment\.[0-9]+\.o|aliases\.cpp|extra\.helpers|-xc\+\+-header'
} | ForEach-Object { Write-Host $_ }
}

- name: Generate and build Python bindings
if: ${{inputs.mrbind && matrix.vcpkg_triplet != 'x64-windows-meshlib-iterator-debug'}}
shell: cmd
env:
MSYS2_DIR: C:\msys64
# Note that `\` doesn't work here as a line continuation, and will lead to weird errors.
run: |
call "${{matrix.vc-path}}\Common7\Tools\VsDevCmd.bat" -arch=amd64 ${{ fromJSON('["", "-vcvars_ver=14.2"]')[matrix.cxx_compiler == 'msvc-2019'] }}
Expand Down Expand Up @@ -241,6 +349,101 @@ jobs:
timeout-minutes: 10
run: source\x64\${{ matrix.config }}\MRTest.exe

- name: Diagnostic — Python bindings post-Unit-Tests
# Fires regardless of Unit Tests outcome to capture state when
# MRTest's embedded-python smoke test trips
# `ImportError: initialization failed` (see PR discussion).
# Shows: which .pyd were built, what they export and link to,
# what python.dll MREmbeddedPython.dll resolves, what a
# standalone py -3.12 import does (real traceback instead of
# CPython's wrapped "initialization failed").
if: ${{ always() }}
shell: pwsh
continue-on-error: true
run: |
$cfg = '${{ matrix.config }}'
$buildDir = Join-Path $Env:GITHUB_WORKSPACE "source\x64\$cfg"
$meshlib = Join-Path $buildDir 'meshlib'

Write-Host "=== build dir top-level (DLL/PYD/EXE) ==="
if (-not (Test-Path $buildDir)) { Write-Host "MISSING: $buildDir"; exit 0 }
Get-ChildItem $buildDir -File | Where-Object { $_.Name -match '\.(dll|pyd|exe)$' } | Sort-Object Name | Format-Table Name, Length -AutoSize | Out-String -Width 200

Write-Host "=== meshlib/ contents ==="
if (Test-Path $meshlib) {
Get-ChildItem $meshlib -Recurse | Sort-Object FullName | Format-Table FullName, Length -AutoSize | Out-String -Width 200
} else { Write-Host "MISSING: $meshlib" }

$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
$vs = & $vswhere -latest -property installationPath
$dumpbin = Get-ChildItem -Path "$vs\VC\Tools\MSVC" -Recurse -Filter dumpbin.exe -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -like "*Hostx64\x64*" } | Select-Object -First 1 -ExpandProperty FullName
Write-Host "dumpbin: $dumpbin"

function Inspect($path) {
if (-not (Test-Path $path)) { Write-Host "MISSING: $path"; return }
Write-Host ""
Write-Host "--- $path ---"
Write-Host "[PyInit_* exports]"
& $dumpbin /exports $path 2>&1 | Select-String -Pattern 'PyInit_' | ForEach-Object { Write-Host $_.Line }
Write-Host "[dependents (python/MR/msvcp/VCRUNTIME/api-ms-win-crt)]"
& $dumpbin /dependents $path 2>&1 | Select-String -Pattern 'python|^\s*MR|msvcp|VCRUNTIME|api-ms-win-crt' | ForEach-Object { Write-Host $_.Line }
}

Inspect (Join-Path $buildDir 'MRTest.exe')
Inspect (Join-Path $buildDir 'MREmbeddedPython.dll')
Inspect (Join-Path $buildDir 'MRPython.dll')
foreach ($p in @('mrmeshpy.pyd','mrviewerpy.pyd','mrmeshnumpypy.pyd','mrcudapy.pyd')) {
Inspect (Join-Path $meshlib $p)
}

Write-Host ""
Write-Host "=== py launcher inventory ==="
& py -0p 2>&1

Write-Host ""
Write-Host "=== standalone import attempt (py -3.12) ==="
Push-Location $buildDir
try {
$env:PYTHONPATH = $buildDir
& py -3.12 -c @"
import sys, os
print('python:', sys.version)
print('exe:', sys.executable)
print('prefix:', sys.prefix)
print('PYTHONPATH:', os.environ.get('PYTHONPATH'))
print('---')
try:
import meshlib
print('meshlib OK at', meshlib.__file__)
except BaseException as e:
import traceback
traceback.print_exc()
sys.exit(2)
try:
import meshlib.mrmeshpy as m
print('mrmeshpy OK at', m.__file__)
except BaseException as e:
import traceback
traceback.print_exc()
sys.exit(3)
"@
Write-Host "exit code: $LASTEXITCODE"
} finally { Pop-Location }

Write-Host ""
Write-Host "=== vcpkg python.dll(s) ==="
foreach ($d in @('C:\vcpkg\installed\x64-windows-meshlib\bin', 'C:\vcpkg\installed\x64-windows-meshlib\debug\bin')) {
if (Test-Path $d) {
Get-ChildItem $d -Filter 'python*.dll' -ErrorAction SilentlyContinue | Format-Table FullName, Length -AutoSize | Out-String -Width 200
}
}

Write-Host ""
Write-Host "=== where.exe python3.dll / python312.dll ==="
where.exe python3.dll 2>&1
where.exe python312.dll 2>&1

- name: C Unit Tests
if: ${{inputs.mrbind_c && matrix.build_system == 'CMake'}}
timeout-minutes: 10
Expand Down
12 changes: 10 additions & 2 deletions .github/workflows/pip-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -307,15 +307,23 @@ jobs:
- name: Build
run: msbuild -m source\MeshLib.sln -p:Configuration=Release

- name: Install MSYS2 for MRBind
uses: ./.github/actions/install-msys2-mrbind
- name: Install MRBind toolchain (clang 18.1.8 pinned) into runner MSYS2
# See build-test-windows.yml's matching step for rationale.
shell: pwsh
run: |
C:\msys64\msys2_shell.cmd -no-start -defterm -here -c "set -e && pacman -Sy --noconfirm"
C:\msys64\msys2_shell.cmd -no-start -defterm -here -c "set -e && bash scripts/mrbind/msys2_download_packages.sh _clang18 && bash scripts/mrbind/msys2_install_packages.sh _clang18"

- name: Build MRBind
shell: cmd
env:
MSYS2_DIR: C:\msys64
run: call ./scripts/mrbind/install_mrbind_windows_msys2.bat

- name: Generate and build MRBind bindings
shell: cmd
env:
MSYS2_DIR: C:\msys64
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat" -arch=amd64
call ./scripts/mrbind/generate_win.bat -B --trace FOR_WHEEL=1
Expand Down
23 changes: 23 additions & 0 deletions scripts/diag/clang-argv-shim.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash
# Diagnostic shim for clang++. Logs every argv element (text + hex) to
# `$DIAG_LOG_DIR/clang-argv.log`, then exec's the real clang++.
# Used to capture exactly what bash passes to clang during the
# MB_PB11_ADJUST_NAMES PCH ↔ fragment macro-mismatch investigation.

LOG_DIR="${DIAG_LOG_DIR:-/c/diag}"
mkdir -p "$LOG_DIR"
LOG="$LOG_DIR/clang-argv.log"

{
printf '====\nINVOCATION pid=%d ppid=%d argc=%d cwd=%s\n' "$$" "$PPID" "$#" "$(pwd)"
i=0
for a in "$@"; do
printf 'ARGV[%d]_TEXT: %s\n' "$i" "$a"
printf 'ARGV[%d]_HEX: ' "$i"
printf '%s' "$a" | od -An -tx1 | tr -d ' \n'
printf '\n'
i=$((i+1))
done
} >> "$LOG"

exec /c/msys64/clang64/bin/clang++.exe "$@"
24 changes: 24 additions & 0 deletions scripts/diag/diag-bash-shim.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash
# Diagnostic shim for bash, used as `make SHELL=...`. Logs every argv
# element (text + hex) to `$DIAG_LOG_DIR/shell-recipes.log`, then
# exec's the real bash. Captures the recipe text make passes to bash
# (pre-quote-stripping) so we can compare it against what clang
# actually receives via the clang shim (post-quote-stripping).

LOG_DIR="${DIAG_LOG_DIR:-/c/diag}"
mkdir -p "$LOG_DIR"
LOG="$LOG_DIR/shell-recipes.log"

{
printf '====\nBASH_INVOCATION pid=%d ppid=%d argc=%d\n' "$$" "$PPID" "$#"
i=0
for a in "$@"; do
printf 'ARG[%d]_TEXT: %s\n' "$i" "$a"
printf 'ARG[%d]_HEX: ' "$i"
printf '%s' "$a" | od -An -tx1 | tr -d ' \n'
printf '\n'
i=$((i+1))
done
} >> "$LOG"

exec /usr/bin/bash "$@"
Loading
Loading