#requires -version 5.1 [CmdletBinding(SupportsShouldProcess = $true)] param( [string]$ProjectDir, [switch]$Force ) Set-StrictMode -Version 2.0 $ErrorActionPreference = 'Stop' function Resolve-FullPath { param([Parameter(Mandatory = $true)][string]$Path) return [IO.Path]::GetFullPath((Resolve-Path -LiteralPath $Path).Path) } function Assert-InsideDirectory { param( [Parameter(Mandatory = $true)][string]$Parent, [Parameter(Mandatory = $true)][string]$Child ) $parentFull = [IO.Path]::GetFullPath($Parent).TrimEnd([char[]]@('\', '/')) $childFull = [IO.Path]::GetFullPath($Child).TrimEnd([char[]]@('\', '/')) $parentPrefix = $parentFull + [IO.Path]::DirectorySeparatorChar if ($childFull -eq $parentFull -or -not $childFull.StartsWith($parentPrefix, [StringComparison]::OrdinalIgnoreCase)) { throw "Refusing to remove path outside project: $childFull" } } function Stop-IfBuildToolsAreRunning { $names = @('qtcreator', 'cmake', 'ninja', 'jom', 'mingw32-make', 'make') $running = Get-Process -ErrorAction SilentlyContinue | Where-Object { $names -contains $_.ProcessName.ToLowerInvariant() } | Sort-Object ProcessName, Id if ($running -and -not $Force) { $summary = ($running | ForEach-Object { "$($_.ProcessName)#$($_.Id)" }) -join ', ' throw "Qt Creator or build tools are running: $summary. Close them first, or rerun with -Force if you are sure." } } function Get-CacheTargets { param([Parameter(Mandatory = $true)][string]$ProjectPath) $literalNames = @( '.qtcreator', '.cmake', '.qt', '.qtc_clangd', 'build', 'out', 'CMakeCache.txt', 'CMakeFiles', 'cmake_install.cmake', 'compile_commands.json', 'CTestTestfile.cmake', 'DartConfiguration.tcl', 'install_manifest.txt', 'Makefile', 'CMakeUserPresets.json' ) $wildcardFilters = @( 'build-*', 'cmake-build-*', '*.user', '*.user.*', '*.autosave' ) $items = New-Object 'System.Collections.Generic.List[System.IO.FileSystemInfo]' foreach ($name in $literalNames) { $path = Join-Path $ProjectPath $name if (Test-Path -LiteralPath $path) { $items.Add((Get-Item -LiteralPath $path -Force)) } } foreach ($filter in $wildcardFilters) { Get-ChildItem -LiteralPath $ProjectPath -Force -Filter $filter -ErrorAction SilentlyContinue | ForEach-Object { $items.Add($_) } } $seen = @{} foreach ($item in $items) { if (-not $seen.ContainsKey($item.FullName)) { $seen[$item.FullName] = $true $item } } } if ([string]::IsNullOrWhiteSpace($ProjectDir)) { if (-not [string]::IsNullOrWhiteSpace($PSScriptRoot)) { $ProjectDir = $PSScriptRoot } elseif (-not [string]::IsNullOrWhiteSpace($PSCommandPath)) { $ProjectDir = Split-Path -Parent $PSCommandPath } else { $ProjectDir = (Get-Location).Path } } $projectPath = Resolve-FullPath -Path $ProjectDir if (-not (Test-Path -LiteralPath (Join-Path $projectPath 'CMakeLists.txt'))) { Write-Warning "CMakeLists.txt was not found in '$projectPath'. Use -ProjectDir to point at the Qt project root." } Stop-IfBuildToolsAreRunning Write-Host "Project: $projectPath" Write-Host 'Mode: delete current project Qt/CMake cache directly.' $targets = @(Get-CacheTargets -ProjectPath $projectPath) if ($targets.Count -eq 0) { Write-Host 'No cache files found.' exit 0 } foreach ($target in $targets) { Assert-InsideDirectory -Parent $projectPath -Child $target.FullName if ($PSCmdlet.ShouldProcess($target.FullName, 'Remove Qt/CMake cache')) { Remove-Item -LiteralPath $target.FullName -Recurse -Force Write-Host "Removed: $($target.FullName)" } } Write-Host 'Done.'