#Requires -Version 5.1 <# .SYNOPSIS LVGL PC 模拟器一键构建(Visual Studio 版本自适应,x64)。 .DESCRIPTION 不同开发机安装的 VS 版本不同,CMake 生成器必须与本机 VS 大版本一致, 因此构建入口不写死生成器:本脚本用 vswhere 自动探测本机 Visual Studio (VS / BuildTools 均可),按大版本映射 CMake 生成器,取已安装的最高版本: 16 = "Visual Studio 16 2019" 17 = "Visual Studio 17 2022" 18 = "Visual Studio 18 2026" 若 build/ 目录缓存的生成器与探测结果不一致(换机/升级 VS 后), 自动删除 build/ 重新配置,避免 MSBuild 报生成器不匹配。 退出码:0=成功;1=构建失败;3=环境预检失败(无 cmake / 无 VS / VS 版本过新)。 .PARAMETER Config 构建配置,默认 Debug(可选 Release)。 .PARAMETER Clean 强制删除 build/ 后全量重建。 .EXAMPLE & 'simulator\build_sim.ps1' # 仓库根目录执行,日常增量构建 & 'simulator\build_sim.ps1' -Clean # 全量重建 & 'simulator\build_sim.ps1' -Config Release # Release 构建 #> param( [ValidateSet('Debug', 'Release')] [string]$Config = 'Debug', [switch]$Clean ) $ErrorActionPreference = 'Stop' # 本脚本位于 simulator/ 目录 $simDir = $PSScriptRoot $buildDir = Join-Path $simDir 'build' # --- 1. 环境预检 ----------------------------------------------------------- $cmake = Get-Command cmake -ErrorAction SilentlyContinue if (-not $cmake) { Write-Host '[build_sim] 预检失败:PATH 中找不到 cmake' -ForegroundColor Red exit 3 } # vswhere:DTU_VSWHERE 显式覆盖 > %ProgramFiles(x86)% 推导(不保留固定 C 盘值) $vswhere = $env:DTU_VSWHERE if ($vswhere) { if (-not (Test-Path -LiteralPath $vswhere)) { Write-Host "[build_sim] 预检失败:DTU_VSWHERE 已设置但文件不存在:$vswhere" -ForegroundColor Red exit 3 } } elseif (${env:ProgramFiles(x86)}) { $vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio\Installer\vswhere.exe' } if (-not $vswhere -or -not (Test-Path -LiteralPath $vswhere)) { Write-Host '[build_sim] 预检失败:未找到 vswhere(本机未安装 Visual Studio / BuildTools,或布局非标准;可用 DTU_VSWHERE 指向 vswhere.exe 完整路径)' -ForegroundColor Red exit 3 } # --- 2. 探测 VS 大版本 → 选择生成器 ---------------------------------------- $raw = & $vswhere -products * -format json $instances = @($raw | ConvertFrom-Json) # 单实例时 PS5.1 返回裸对象,@() 统一成数组 $instances = $instances | Where-Object { $_ -and $_.installationVersion } if (-not $instances) { Write-Host '[build_sim] 预检失败:vswhere 未返回任何 VS 实例' -ForegroundColor Red exit 3 } $best = $instances | Sort-Object { [version]$_.installationVersion } | Select-Object -Last 1 $major = [version]$best.installationVersion switch ($major.Major) { 16 { $generator = 'Visual Studio 16 2019' } 17 { $generator = 'Visual Studio 17 2022' } 18 { $generator = 'Visual Studio 18 2026' } default { Write-Host "[build_sim] 预检失败:不支持的 VS 大版本 $($major.Major)($($best.installationPath)),仅支持 16/17/18" -ForegroundColor Red exit 3 } } Write-Host "[build_sim] 探测到 VS $($best.installationVersion) -> 生成器 '$generator'" # 删除 build/ 目录(带重试:抗杀软瞬时锁/文件占用;彻底失败则提示用户) function Remove-BuildDir([string]$Dir) { for ($i = 1; $i -le 3; $i++) { try { Remove-Item $Dir -Recurse -Force -ErrorAction Stop return $true } catch { if ($i -lt 3) { Write-Host "[build_sim] build/ 删除失败(可能有文件被占用),重试 $i/3 ..." Start-Sleep -Seconds 2 } } } Write-Host '[build_sim] 无法删除 build/:若模拟器窗口仍开着,请先关闭再重试' -ForegroundColor Red return $false } # --- 3. 生成器一致性检查(缓存不匹配则删 build/ 重建)----------------------- if ($Clean -and (Test-Path $buildDir)) { if (-not (Remove-BuildDir $buildDir)) { exit 3 } Write-Host '[build_sim] -Clean:已删除 build/' } $cache = Join-Path $buildDir 'CMakeCache.txt' if (Test-Path $cache) { # CMake 缓存中 CMAKE_GENERATOR 的类型随版本为 STRING 或 INTERNAL,统一按行首匹配 $cached = (Select-String -Path $cache -Pattern '^CMAKE_GENERATOR:' | Select-Object -First 1).Line -replace '^CMAKE_GENERATOR:[A-Z]+=', '' if ($cached -cne $generator) { Write-Host "[build_sim] build/ 由 '$cached' 配置,与本机 '$generator' 不符 -> 删除重建" if (-not (Remove-BuildDir $buildDir)) { exit 3 } } } # --- 4. 配置 + 构建 --------------------------------------------------------- if (-not (Test-Path (Join-Path $buildDir 'CMakeCache.txt'))) { Write-Host '[build_sim] CMake 配置 ...' & cmake -S $simDir -B $buildDir -G $generator -A x64 if ($LASTEXITCODE -ne 0) { Write-Host '[build_sim] CMake 配置失败' -ForegroundColor Red exit $LASTEXITCODE } } Write-Host "[build_sim] 构建($Config)..." & cmake --build $buildDir --config $Config if ($LASTEXITCODE -ne 0) { Write-Host '[build_sim] 构建失败' -ForegroundColor Red exit $LASTEXITCODE } $exe = Join-Path $buildDir (Join-Path $Config 'lvgl_sim.exe') if (Test-Path $exe) { Write-Host "[build_sim] OK:$exe" -ForegroundColor Green exit 0 } Write-Host "[build_sim] 构建退出码 0 但未找到 $exe" -ForegroundColor Red exit 1