# Toolchain detection. Picks a backend appropriate for the host arch: # x64 host -> MSVC (x64) or MinGW (x86_64), Rust target = host default or x86_64-pc-windows-gnu # ARM64 host -> CLANGARM64 (msys2) or MinGW (x86_64, emulated, warned), Rust target = aarch64-pc-windows-gnullvm # Dot-source this file: . "$PSScriptRoot\_toolchain.ps1" $ErrorActionPreference = 'Stop' function Get-HostArch { if ($env:PROCESSOR_ARCHITECTURE -eq 'ARM64' -or $env:PROCESSOR_ARCHITEW6432 -eq 'ARM64') { return 'arm64' } return 'x64' } function Initialize-VsEnv { param([string]$VcVars) $tmp = New-TemporaryFile try { cmd /c "`"$VcVars`" x64 >NUL && set" | Out-File -FilePath $tmp -Encoding ascii foreach ($line in Get-Content $tmp) { if ($line -match '^([^=]+)=(.*)$') { Set-Item -Path "env:$($Matches[1])" -Value $Matches[2] } } } finally { Remove-Item $tmp -Force -ErrorAction SilentlyContinue } } function Find-VsInstall { $vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe' if (-not (Test-Path $vswhere)) { $vswhere = Join-Path $env:ProgramFiles 'Microsoft Visual Studio\Installer\vswhere.exe' } if (-not (Test-Path $vswhere)) { return $null } $install = & $vswhere -latest -products * ` -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 ` -property installationPath 2>$null if (-not $install) { return $null } $vcvars = Join-Path $install 'VC\Auxiliary\Build\vcvars64.bat' if (Test-Path $vcvars) { return $vcvars } return $null } function Find-MingwBin { if ($env:MINGW_PREFIX -and (Test-Path (Join-Path $env:MINGW_PREFIX 'g++.exe'))) { return $env:MINGW_PREFIX } $gxx = Get-Command g++.exe -ErrorAction SilentlyContinue if ($gxx) { return (Split-Path $gxx.Source -Parent) } foreach ($p in @( 'C:\msys64\mingw64\bin', 'C:\msys64\ucrt64\bin', 'C:\mingw64\bin', 'C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin' )) { if (Test-Path (Join-Path $p 'g++.exe')) { return $p } } return $null } function Find-ClangArm64Bin { if ($env:CLANGARM64_PREFIX -and (Test-Path (Join-Path $env:CLANGARM64_PREFIX 'clang++.exe'))) { return $env:CLANGARM64_PREFIX } foreach ($p in @('C:\msys64\clangarm64\bin')) { if (Test-Path (Join-Path $p 'clang++.exe')) { return $p } } return $null } function Get-Toolchain { $hostArch = Get-HostArch if ($hostArch -eq 'arm64') { $clangBin = Find-ClangArm64Bin if ($clangBin) { return [pscustomobject]@{ Kind = 'clangarm64' Ready = $true Bin = $clangBin CargoTarget = 'aarch64-pc-windows-gnullvm' } } $mingw = Find-MingwBin if ($mingw) { Write-Warning "ARM64 host but only x86_64 MinGW found; resulting binaries will run under emulation and may crash at startup. Install msys2 CLANGARM64 (pacman -S mingw-w64-clang-aarch64-toolchain)." return [pscustomobject]@{ Kind = 'mingw'; Ready = $true; MingwBin = $mingw; CargoTarget = 'x86_64-pc-windows-gnu' } } throw "No ARM64 C++ toolchain found. Install msys2 CLANGARM64 (pacman -S mingw-w64-clang-aarch64-toolchain) or Visual Studio ARM64 C++ tools." } if (Get-Command cl.exe -ErrorAction SilentlyContinue) { return [pscustomobject]@{ Kind = 'msvc'; Ready = $true; VcVars = $null; CargoTarget = '' } } $vcvars = Find-VsInstall if ($vcvars) { return [pscustomobject]@{ Kind = 'msvc'; Ready = $false; VcVars = $vcvars; CargoTarget = '' } } $mingw = Find-MingwBin if ($mingw) { return [pscustomobject]@{ Kind = 'mingw'; Ready = $true; MingwBin = $mingw; CargoTarget = 'x86_64-pc-windows-gnu' } } throw "No C++ toolchain found. Install Visual Studio Build Tools (with the C++ workload) or MinGW-w64." } function Initialize-Toolchain { param([pscustomobject]$Toolchain) if ($Toolchain.Kind -eq 'msvc' -and -not $Toolchain.Ready) { Write-Host "Importing MSVC environment from $($Toolchain.VcVars)" Initialize-VsEnv -VcVars $Toolchain.VcVars } if ($Toolchain.Kind -eq 'mingw' -and $Toolchain.MingwBin -and ($env:PATH -notlike "*$($Toolchain.MingwBin)*")) { $env:PATH = "$($Toolchain.MingwBin);$env:PATH" } if ($Toolchain.Kind -eq 'clangarm64' -and $Toolchain.Bin -and ($env:PATH -notlike "*$($Toolchain.Bin)*")) { $env:PATH = "$($Toolchain.Bin);$env:PATH" } }