138 lines
4.3 KiB
PowerShell
138 lines
4.3 KiB
PowerShell
#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"
|
|
}
|
|
}
|
|
|
|
# 函数作用:检查 Qt Creator、CMake、Ninja 等构建相关进程是否正在运行,防止清理缓存时与构建过程冲突。
|
|
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."
|
|
}
|
|
}
|
|
|
|
# 函数作用:收集当前 Qt 项目下可安全清理的 CMake/Qt Creator 缓存文件和构建目录,并去除重复项。
|
|
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.'
|