ConfigMSVC.ps1

application/octet-stream

Filename: ConfigMSVC.ps1
Type: application/octet-stream
Part: 1
Message: Re: [PATCH] Fix ARM64/MSVC atomic memory ordering issues on Win11 by adding explicit DMB ​barriers
# 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