<# Локальная сборка преднастроенного RustDesk-клиента под Windows (GUSIK-PC). Делает: клон rustdesk@пин -> preconfigure (вшить сервер+ключ) -> python build.py --flutter -> dist/. Тулчейн (Rust 1.75 / LLVM 15 / Flutter 3.24.5 / vcpkg@пин) должен быть уже поднят — скрипт делает preflight-проверку и подсказывает, чего не хватает. Запуск: pwsh -File scripts\build-windows.ps1 Опции: -Clean (снести клон и склонировать заново) #> [CmdletBinding()] param( [switch]$Clean, [switch]$SkipBuild # только клон+preconfigure, без компиляции (для отладки) ) $ErrorActionPreference = 'Stop' $root = Split-Path -Parent $PSScriptRoot # корень overlay-репо $src = Join-Path $root 'rustdesk' # клон апстрима $dist = Join-Path $root 'dist' # --- читаем пины --- $pins = @{} Get-Content (Join-Path $root 'upstream.txt') | Where-Object { $_ -match '^\s*[A-Z]' } | ForEach-Object { $k,$v = $_ -split '=',2; $pins[$k.Trim()] = $v.Trim() } $TAG = $pins['RUSTDESK_TAG'] $REPO = $pins['RUSTDESK_REPO'] Write-Host "== RustDesk custom build == tag=$TAG" -ForegroundColor Cyan # --- загрузка config/server.env --- $envFile = Join-Path $root 'config\server.env' if (-not (Test-Path $envFile)) { throw "Нет $envFile. Скопируй config\server.env.example -> config\server.env и заполни RUSTDESK_SERVER/RUSTDESK_PUB_KEY." } Get-Content $envFile | Where-Object { $_ -match '^\s*[A-Z].*=' } | ForEach-Object { $k,$v = $_ -split '=',2 Set-Item -Path "Env:$($k.Trim())" -Value $v.Trim() } if (-not $env:RUSTDESK_SERVER -or -not $env:RUSTDESK_PUB_KEY) { throw "В config\server.env не заданы RUSTDESK_SERVER и/или RUSTDESK_PUB_KEY." } # --- preflight тулчейна --- function Need($name, $test, $hint) { if (-not (& $test)) { Write-Host " [нет] $name — $hint" -ForegroundColor Yellow; return $false } Write-Host " [ok] $name" -ForegroundColor Green; return $true } Write-Host "Preflight тулчейна:" -ForegroundColor Cyan $ok = $true $ok = (Need 'git' { Get-Command git -EA SilentlyContinue } 'установи Git for Windows') -and $ok $ok = (Need 'bash' { Get-Command bash -EA SilentlyContinue } 'нужен git-bash для preconfigure.sh') -and $ok $ok = (Need 'python' { Get-Command python -EA SilentlyContinue } 'нужен Python 3 для build.py') -and $ok $ok = (Need 'rustup' { Get-Command rustup -EA SilentlyContinue } 'установи rustup') -and $ok $ok = (Need 'flutter' { Get-Command flutter -EA SilentlyContinue } "Flutter $($pins['FLUTTER_VERSION']) stable в PATH") -and $ok $ok = (Need 'vcpkg' { $env:VCPKG_ROOT -and (Test-Path (Join-Path $env:VCPKG_ROOT 'vcpkg.exe')) } "склонируй vcpkg@$($pins['VCPKG_COMMIT_ID']), задай VCPKG_ROOT") -and $ok $ok = (Need 'LLVM' { $env:LIBCLANG_PATH -and (Test-Path $env:LIBCLANG_PATH) } "LLVM $($pins['LLVM_VERSION']), задай LIBCLANG_PATH") -and $ok if (-not $ok) { throw "Тулчейн неполный — см. docs\CODEMAP.md (раздел 'Windows toolchain')." } # --- клон / обновление до пина --- if ($Clean -and (Test-Path $src)) { Remove-Item -Recurse -Force $src } if (-not (Test-Path $src)) { Write-Host "Клонирую rustdesk@$TAG ..." -ForegroundColor Cyan git clone --branch $TAG --depth 1 --recurse-submodules --shallow-submodules $REPO $src } else { Write-Host "Клон уже есть — сбрасываю патчи до чистого $TAG ..." -ForegroundColor Cyan git -C $src checkout -- . git -C $src submodule foreach --recursive 'git checkout -- .' } # зафиксировать Rust 1.75 для этого дерева Push-Location $src rustup override set $pins['RUST_VERSION'] | Out-Null Pop-Location # --- preconfigure: вшить сервер+ключ --- Write-Host "Preconfigure (вшиваю сервер+ключ)..." -ForegroundColor Cyan bash "$root/scripts/preconfigure.sh" "$src" if ($SkipBuild) { Write-Host "SkipBuild — остановился после preconfigure." -ForegroundColor Yellow; return } # --- сборка --- Write-Host "Сборка: python build.py --flutter (первый раз долго: vcpkg ffmpeg/aom)..." -ForegroundColor Cyan Push-Location $src python build.py --flutter Pop-Location # --- собрать артефакт --- New-Item -ItemType Directory -Force $dist | Out-Null $exe = Get-ChildItem -Path $src -Recurse -Filter 'rustdesk*.exe' -EA SilentlyContinue | Where-Object { $_.FullName -match 'Release|portable' } | Select-Object -First 1 if ($exe) { Copy-Item $exe.FullName (Join-Path $dist $exe.Name) -Force Write-Host "Готово: $(Join-Path $dist $exe.Name)" -ForegroundColor Green } else { Write-Host "Сборка завершилась, но .exe не найден автоматически — глянь $src\build и $src\flutter\build." -ForegroundColor Yellow }