From 8c75f26cc194a62b33da63a5b963a9148b30e8ad Mon Sep 17 00:00:00 2001 From: FlowmemoryAI <283694809+FlowmemoryAI@users.noreply.github.com> Date: Wed, 13 May 2026 17:58:35 -0500 Subject: [PATCH] Fix Windows MSVC prerequisite setup --- INSTALL_FLOWCHAIN_WINDOWS.ps1 | 73 +++++++++++++++++++++++ README.md | 5 +- docs/EASY_SECOND_COMPUTER_SETUP.md | 3 +- docs/FLOWCHAIN_SECOND_COMPUTER_SETUP.md | 2 + infra/scripts/flowchain-check-prereqs.ps1 | 67 +++++++++++++++++++++ 5 files changed, 147 insertions(+), 3 deletions(-) diff --git a/INSTALL_FLOWCHAIN_WINDOWS.ps1 b/INSTALL_FLOWCHAIN_WINDOWS.ps1 index b9f4726a..1004f5de 100644 --- a/INSTALL_FLOWCHAIN_WINDOWS.ps1 +++ b/INSTALL_FLOWCHAIN_WINDOWS.ps1 @@ -112,6 +112,44 @@ function Test-Python { return $false } +function Test-MsvcBuildTools { + Refresh-Path + + if (Get-Command link.exe -ErrorAction SilentlyContinue) { + return $true + } + + $programFilesX86 = [Environment]::GetFolderPath("ProgramFilesX86") + $vswhere = if ([string]::IsNullOrWhiteSpace($programFilesX86)) { + $null + } else { + Join-Path $programFilesX86 "Microsoft Visual Studio\Installer\vswhere.exe" + } + + if (-not [string]::IsNullOrWhiteSpace($vswhere) -and (Test-Path -LiteralPath $vswhere)) { + $installPath = (& $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath 2>$null | Select-Object -First 1) + if (-not [string]::IsNullOrWhiteSpace($installPath)) { + return $true + } + } + + $candidateRoots = @( + (Join-Path $env:ProgramFiles "Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC"), + (Join-Path $env:ProgramFiles "Microsoft Visual Studio\2022\Community\VC\Tools\MSVC") + ) + if (-not [string]::IsNullOrWhiteSpace($programFilesX86)) { + $candidateRoots += Join-Path $programFilesX86 "Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC" + } + + foreach ($root in $candidateRoots) { + if (Test-Path -LiteralPath $root) { + return $true + } + } + + return $false +} + function Install-WingetPackage { param( [string]$DisplayName, @@ -219,6 +257,39 @@ function Install-Rust { Write-Ok "Rust and Cargo installed" } +function Install-MsvcBuildTools { + if (Test-MsvcBuildTools) { + Write-Ok "Visual Studio Build Tools C++ workload is already installed" + return + } + + if ($SkipToolInstall) { + Write-Warn "Visual Studio Build Tools C++ workload is missing, and -SkipToolInstall was set" + return + } + + Write-Step "Install Visual Studio Build Tools C++ workload" + Invoke-Checked "winget" @( + "install", + "--id", + "Microsoft.VisualStudio.2022.BuildTools", + "--exact", + "--source", + "winget", + "--accept-package-agreements", + "--accept-source-agreements", + "--override", + "--quiet --wait --norestart --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended" + ) + Refresh-Path + + if (-not (Test-MsvcBuildTools)) { + throw "Visual Studio Build Tools installed, but the C++ workload was not detected. Reboot or reopen PowerShell, then rerun this installer." + } + + Write-Ok "Visual Studio Build Tools C++ workload installed" +} + function Get-GitBash { Refresh-Path @@ -290,6 +361,7 @@ function Show-ToolStatus { @{ Name = "npm"; Available = (Test-Tool "npm") }, @{ Name = "cargo"; Available = (Test-Tool "cargo") }, @{ Name = "rustc"; Available = (Test-Tool "rustc") }, + @{ Name = "msvc-build-tools"; Available = (Test-MsvcBuildTools) }, @{ Name = "forge"; Available = (Test-Tool "forge") }, @{ Name = "python3"; Available = (Test-Python) } ) @@ -328,6 +400,7 @@ function Install-Tools { Install-Python Install-Rust + Install-MsvcBuildTools Install-Foundry } diff --git a/README.md b/README.md index 40361170..bfa62746 100644 --- a/README.md +++ b/README.md @@ -105,8 +105,9 @@ npm run flowchain:demo npm run flowchain:export ``` -Run the merged-surface smoke path when Foundry, Python, dashboard dependencies, -and crypto dependencies are installed: +Run the merged-surface smoke path when Foundry, Python, Visual Studio Build +Tools C++ workload, dashboard dependencies, and crypto dependencies are +installed: ```powershell npm install --prefix apps/dashboard diff --git a/docs/EASY_SECOND_COMPUTER_SETUP.md b/docs/EASY_SECOND_COMPUTER_SETUP.md index b5a666fc..15372b20 100644 --- a/docs/EASY_SECOND_COMPUTER_SETUP.md +++ b/docs/EASY_SECOND_COMPUTER_SETUP.md @@ -15,7 +15,8 @@ The root installer installs or verifies: 2. Node.js LTS with npm 3. Python 3 4. Rust with Cargo -5. Foundry +5. Visual Studio Build Tools with the C++ workload +6. Foundry Foundry is installed through Git Bash because Foundry's Windows installer does not support PowerShell directly. diff --git a/docs/FLOWCHAIN_SECOND_COMPUTER_SETUP.md b/docs/FLOWCHAIN_SECOND_COMPUTER_SETUP.md index 4c3f91bb..a6ef8096 100644 --- a/docs/FLOWCHAIN_SECOND_COMPUTER_SETUP.md +++ b/docs/FLOWCHAIN_SECOND_COMPUTER_SETUP.md @@ -20,6 +20,8 @@ installer installs or verifies them for the user: - Git for Windows. - Node.js LTS with npm. - Rust toolchain with Cargo. +- Visual Studio Build Tools with the C++ workload, which Rust needs on + Windows to compile the local devnet crate. - Foundry. - Python 3. diff --git a/infra/scripts/flowchain-check-prereqs.ps1 b/infra/scripts/flowchain-check-prereqs.ps1 index 065d5d2a..470e3673 100644 --- a/infra/scripts/flowchain-check-prereqs.ps1 +++ b/infra/scripts/flowchain-check-prereqs.ps1 @@ -54,12 +54,79 @@ function Add-Check { }) } +function Find-MsvcBuildTools { + $linkCommand = Get-Command "link.exe" -ErrorAction SilentlyContinue + if ($linkCommand) { + return [pscustomobject]@{ + Found = $true + Version = "link.exe at $($linkCommand.Source)" + } + } + + $programFilesX86 = [Environment]::GetFolderPath("ProgramFilesX86") + $vswhere = if ([string]::IsNullOrWhiteSpace($programFilesX86)) { + $null + } else { + Join-Path $programFilesX86 "Microsoft Visual Studio\Installer\vswhere.exe" + } + + if (-not [string]::IsNullOrWhiteSpace($vswhere) -and (Test-Path -LiteralPath $vswhere)) { + $installPath = (& $vswhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath 2>$null | Select-Object -First 1) + if (-not [string]::IsNullOrWhiteSpace($installPath)) { + return [pscustomobject]@{ + Found = $true + Version = "Visual C++ tools at $installPath" + } + } + } + + $candidateRoots = @( + (Join-Path $env:ProgramFiles "Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC"), + (Join-Path $env:ProgramFiles "Microsoft Visual Studio\2022\Community\VC\Tools\MSVC") + ) + if (-not [string]::IsNullOrWhiteSpace($programFilesX86)) { + $candidateRoots += Join-Path $programFilesX86 "Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC" + } + + foreach ($root in $candidateRoots) { + if (Test-Path -LiteralPath $root) { + return [pscustomobject]@{ + Found = $true + Version = "Visual C++ tools at $root" + } + } + } + + return [pscustomobject]@{ + Found = $false + Version = "" + } +} + +function Add-MsvcCheck { + param([System.Collections.ArrayList] $Checks) + + $msvc = Find-MsvcBuildTools + [void] $Checks.Add([pscustomobject]@{ + Name = "MSVC C++ build tools" + Required = $true + Status = if ($msvc.Found) { "ok" } else { "missing" } + Version = $msvc.Version + NextStep = if ($msvc.Found) { + "" + } else { + "Install Visual Studio Build Tools 2022 with the C++ workload, then reopen PowerShell." + } + }) +} + $checks = New-Object System.Collections.ArrayList Add-Check -Checks $checks -Name "Git" -Command "git" -Required $true Add-Check -Checks $checks -Name "Node.js" -Command "node" -Required $true Add-Check -Checks $checks -Name "npm" -Command "npm" -Required $true Add-Check -Checks $checks -Name "Rust cargo" -Command "cargo" -Required $true Add-Check -Checks $checks -Name "Rust compiler" -Command "rustc" -Required $true +Add-MsvcCheck -Checks $checks Add-Check -Checks $checks -Name "Foundry forge" -Command "forge" -Required $true Add-Check -Checks $checks -Name "Python" -Command "python" -Required:$Strict