ConfigMSVC.ps1
application/octet-stream
Filename: ConfigMSVC.ps1
Type: application/octet-stream
Part: 1
# ARM64 Development Environment Setup with Auto-Detection
# Configures environment variables and runs Meson setup
# ============================================
# Visual Studio and MSVC Auto-Detection
# ============================================
function Find-VisualStudioPath {
<#
.SYNOPSIS
Locates the Visual Studio installation directory using vswhere
Works with Visual Studio 2022, 2026, and later
#>
# vswhere.exe is always in ProgramFiles(x86)
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
if (Test-Path $vswhere) {
try {
# Get the latest version of Visual Studio
$vsPath = & $vswhere -latest -property installationPath 2>$null
if ($vsPath -and (Test-Path $vsPath)) {
Write-Host "Found Visual Studio at: $vsPath" -ForegroundColor Green
return $vsPath
}
}
catch {
Write-Warning "vswhere.exe found but failed to execute: $_"
}
}
# Fallback: Scan the entire Visual Studio directory tree
$vsRoot = "${env:ProgramFiles}\Microsoft Visual Studio"
if (Test-Path $vsRoot) {
Write-Host "Searching for Visual Studio installations in $vsRoot" -ForegroundColor Yellow
# Get year directories sorted by newest first (17 = 2022, 18 = 2026, etc.)
$yearDirs = Get-ChildItem -Path $vsRoot -Directory -ErrorAction SilentlyContinue | Sort-Object Name -Descending
foreach ($yearDir in $yearDirs) {
# Get edition directories (Community, Professional, Enterprise)
$editions = Get-ChildItem -Path $yearDir.FullName -Directory -ErrorAction SilentlyContinue
foreach ($edition in $editions) {
# Check if it has the VC tools
if (Test-Path (Join-Path $edition.FullName "VC\Tools\MSVC")) {
Write-Host "Found Visual Studio at: $($edition.FullName)" -ForegroundColor Green
return $edition.FullName
}
}
}
}
Write-Error "Visual Studio installation not found."
Write-Error "Checked: $vswhere (vswhere.exe)"
Write-Error "Checked: ${env:ProgramFiles}\Microsoft Visual Studio\"
exit 1
}
function Find-MSVCPath {
<#
.SYNOPSIS
Locates the MSVC compiler toolset and returns the latest version path
#>
param([string]$VSPath)
$msvRoot = Join-Path $VSPath "VC\Tools\MSVC"
if (-not (Test-Path $msvRoot)) {
Write-Error "MSVC toolset not found at $msvRoot"
exit 1
}
# Get the latest MSVC version folder
$msvVersions = Get-ChildItem -Path $msvRoot -Directory | Sort-Object Name -Descending
if ($msvVersions.Count -eq 0) {
Write-Error "No MSVC versions found in $msvRoot"
exit 1
}
return Join-Path $msvRoot $msvVersions[0].Name
}
function Find-WindowsSDKVersion {
<#
.SYNOPSIS
Detects the Windows SDK version from the registry
#>
$regPath = "HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots"
if (Test-Path $regPath) {
$sdkRoot = Get-ItemProperty -Path $regPath -Name KitsRoot10
$sdkRoot = $sdkRoot.KitsRoot10
if (Test-Path (Join-Path $sdkRoot "Include")) {
# Get the latest SDK version folder
$versions = Get-ChildItem -Path (Join-Path $sdkRoot "Include") -Directory |
Where-Object { $_.Name -match '^\d+\.\d+\.\d+\.\d+$' } |
Sort-Object Name -Descending
if ($versions.Count -gt 0) {
return @{
Version = $versions[0].Name
Path = $sdkRoot
}
}
}
}
Write-Error "Windows SDK not found"
exit 1
}
# ============================================
# Main Setup
# ============================================
Write-Host "=== Detecting Visual Studio Installation ===" -ForegroundColor Cyan
$vsPath = Find-VisualStudioPath
Write-Host "Found Visual Studio at: $vsPath" -ForegroundColor Green
Write-Host "`n=== Detecting MSVC Toolset ===" -ForegroundColor Cyan
$msvPath = Find-MSVCPath -VSPath $vsPath
Write-Host "Found MSVC at: $msvPath" -ForegroundColor Green
Write-Host "`n=== Detecting Windows SDK ===" -ForegroundColor Cyan
$sdkInfo = Find-WindowsSDKVersion
$winKitVersion = $sdkInfo.Version
$winKitPath = $sdkInfo.Path
Write-Host "Found Windows SDK $winKitVersion at: $winKitPath" -ForegroundColor Green
# ============================================
# Initialize MSVC Environment with vcvarsarm64.bat
# ============================================
Write-Host "`n=== Initializing MSVC Environment ===" -ForegroundColor Cyan
$vcvarsPath = Join-Path $vsPath "VC\Auxiliary\Build\vcvarsarm64.bat"
if (-not (Test-Path $vcvarsPath)) {
Write-Error "vcvarsarm64.bat not found at $vcvarsPath"
exit 1
}
# Detect Visual Studio version from path
$vsVersion = (Split-Path $vsPath -Parent | Split-Path -Leaf)
Write-Host "Detected Visual Studio version: $vsVersion" -ForegroundColor Yellow
# Map VS directory to version number (17=2022, 18=2026, etc.)
$versionMap = @{
"17" = "17.0"
"18" = "18.0"
"19" = "19.0"
}
$visualStudioVersion = $versionMap[$vsVersion]
if (-not $visualStudioVersion) {
$visualStudioVersion = "$vsVersion.0"
}
Write-Host "Executing: `"$vcvarsPath`"" -ForegroundColor Yellow
$output = cmd /c """$vcvarsPath"" && set"
# Parse and set all environment variables from vcvarsarm64.bat
foreach ($line in $output) {
if ($line -match "^([^=]+)=(.*)$") {
$varName = $matches[1].Trim()
$varValue = $matches[2].Trim()
if ($varName -and $varValue) {
Set-Item -Force -Path "ENV:\$varName" -Value $varValue 2>$null
}
}
}
# Explicitly set required variables for Meson
$env:VSINSTALLDIR = $vsPath
$env:VisualStudioVersion = $visualStudioVersion
$env:VCINSTALLDIR = $msvPath
# Verify critical variables
$requiredVars = @{
"VSINSTALLDIR" = $vsPath
"VisualStudioVersion" = $visualStudioVersion
"VCINSTALLDIR" = $msvPath
}
Write-Host "`nEnvironment variables set:" -ForegroundColor Green
foreach ($var in $requiredVars.GetEnumerator()) {
$value = Get-Item -Path "ENV:\$($var.Key)" -ErrorAction SilentlyContinue
if ($value) {
Write-Host " $($var.Key) = $($value.Value)" -ForegroundColor Green
}
else {
Write-Warning " $($var.Key) not set!"
}
}
Write-Host "MSVC environment initialized" -ForegroundColor Green
# ============================================
# Configure Include Paths
# ============================================
Write-Host "`n=== Configuring Include Paths ===" -ForegroundColor Cyan
$includeList = @(
"$msvPath\include",
"$winKitPath\Include\$winKitVersion\ucrt",
"$winKitPath\Include\$winKitVersion\um",
"$winKitPath\Include\$winKitVersion\shared"
"$vcpkgRoot\installed\arm64-windows\include"
)
$env:INCLUDE = $includeList -join ";"
Write-Host "INCLUDE path configured" -ForegroundColor Green
# Dump INCLUDE
#$env:INCLUDE | ForEach-Object { $_.Split(';') | Select-Object -First 20 }
# ============================================
# Configure Library Paths
# ============================================
Write-Host "`n=== Configuring Library Paths ===" -ForegroundColor Cyan
$libList = @(
"$msvPath\lib\arm64",
"$winKitPath\Lib\$winKitVersion\ucrt\arm64",
"$winKitPath\Lib\$winKitVersion\um\arm64"
"$vcpkgRoot\installed\arm64-windows\lib"
)
$env:LIB = $libList -join ";"
$env:LIBPATH = $env:LIB
Write-Host "LIB and LIBPATH configured" -ForegroundColor Green
# Dump LIB
#$env:LIB | ForEach-Object { $_.Split(';') | Select-Object -First 20 }
# ============================================
# Configure PATH
# ============================================
Write-Host "`n=== Configuring System PATH ===" -ForegroundColor Cyan
$pythonPath = "C:\Python314"
#$pythonPath = Join-Path $env:LocalAppData "Programs\Python\Python314"
$pythonScripts = Join-Path $pythonPath "Scripts"
$pythonUserScripts = Join-Path $env:AppData "Python\Python314\Scripts"
$vcpkgRoot = "C:\tools\vcpkg"
$codeInsiders = Join-Path $env:LocalAppData "Programs\Microsoft VS Code Insiders\bin"
$vsCode = Join-Path $env:LocalAppData "Programs\Microsoft VS Code\bin"
# Perl paths - try Strawberry Perl first, then ActivePerl
$perlPath = $null
$perlCandidates = @(
"C:\Strawberry\perl\bin",
"${env:ProgramFiles}\Strawberry\perl\bin",
"${env:ProgramFiles(x86)}\Strawberry\perl\bin",
"C:\Perl\bin",
"${env:ProgramFiles}\ActivePerl\bin"
)
foreach ($candidate in $perlCandidates) {
if (Test-Path $candidate) {
$perlPath = $candidate
Write-Host "Found Perl at: $perlPath" -ForegroundColor Green
break
}
}
if (-not $perlPath) {
Write-Warning "Perl not found in standard locations. PostgreSQL build may fail."
Write-Warning "Install Strawberry Perl from https://strawberryperl.com/"
}
$pathArray = @(
# ARM64 MSVC compiler
"$msvPath\bin\HostARM64\ARM64",
# ARM64 Python (BEFORE system Python or other tools)
$pythonPath,
$pythonScripts,
$pythonUserScripts,
# Add Perl to PATH
$perlPath,
# ARM64 vcpkg
"$vcpkgRoot\installed\arm64-windows\bin",
# Windows Kits ARM64
"$winKitPath\bin\$winKitVersion\arm64",
# System paths
"$env:SystemRoot\system32",
"$env:SystemRoot",
"$env:SystemRoot\System32\Wbem",
"$env:SystemRoot\System32\WindowsPowerShell\v1.0",
$codeInsiders,
$vsCode,
# Optional tools (but keep at end)
"${env:ProgramFiles}\Git\cmd",
"${env:ProgramFiles}\Neovim\bin",
"${env:ProgramFiles(x86)}\Windows Kits\10\Windows Performance Toolkit",
"${env:ProgramData}\chocolatey\bin",
"${env:ProgramFiles}\CMake\bin",
"C:\tools"
)
# Filter out null/empty entries and non-existent paths
$env:PATH = ($pathArray | Where-Object { $_ -and (Test-Path $_) }) -join ";"
Write-Host "PATH configured" -ForegroundColor Green
# Dump PATH
#$env:PATH | ForEach-Object { $_.Split(';') | Select-Object -First 20 }
# ============================================
# Configure vcpkg and CMake
# ============================================
Write-Host "`n=== Configuring vcpkg and CMake ===" -ForegroundColor Cyan
if (Test-Path $vcpkgRoot) {
$env:VCPKG_ROOT = $vcpkgRoot
$env:CMAKE_PREFIX_PATH = "$vcpkgRoot\installed\arm64-windows"
# Set PKG_CONFIG_PATH for Meson to find vcpkg dependencies
$env:PKG_CONFIG_PATH = "$vcpkgRoot\installed\arm64-windows\lib\pkgconfig"
# Add vcpkg tools to PATH (includes pkg-config, ninja from vcpkg-tool-meson, etc.)
$vcpkgBinPath = "$vcpkgRoot\installed\arm64-windows\bin"
$vcpkgToolsPath = "$vcpkgRoot\tools"
if ($vcpkgBinPath -notin $env:PATH.Split(";")) {
$env:PATH = "$vcpkgBinPath;$env:PATH"
}
if ($vcpkgToolsPath -notin $env:PATH.Split(";")) {
$env:PATH = "$vcpkgToolsPath;$env:PATH"
}
Write-Host "vcpkg configured:" -ForegroundColor Green
Write-Host " VCPKG_ROOT = $env:VCPKG_ROOT" -ForegroundColor Green
Write-Host " CMAKE_PREFIX_PATH = $env:CMAKE_PREFIX_PATH" -ForegroundColor Green
Write-Host " PKG_CONFIG_PATH = $env:PKG_CONFIG_PATH" -ForegroundColor Green
Write-Host " Added to PATH: $vcpkgBinPath" -ForegroundColor Green
}
else {
Write-Warning "vcpkg not found at $vcpkgRoot - skipping vcpkg configuration"
}
# ============================================
# Run Meson Setup
# ============================================
Write-Host "`n=== Running Meson Setup ===" -ForegroundColor Cyan
$mesonBuildDir = "build"
$mesonPrefix = "${env:ProgramFiles}\postgresql"
# Use ninja backend instead of vs, which works better with newer MSVC
$mesonArgs = @(
"setup"
$mesonBuildDir
"--reconfigure"
# "--vsenv"
# "--backend", "vs"
"--backend", "ninja"
"--prefix=$mesonPrefix"
"--buildtype=debugoptimized"
"-Dplperl=disabled"
"-Dextra_lib_dirs=$extraLibDir"
"-Dextra_include_dirs=$extraIncludeDir"
"-Dpkg_config_path=$env:PKG_CONFIG_PATH"
)
Write-Host "Executing: meson $($mesonArgs -join ' ')" -ForegroundColor Yellow
meson @mesonArgs