Files
chanora/tools/build-windows.ps1
EdisonJwa 8094ec7277 docs(release): add Windows build instructions + PowerShell helper
The development host is Linux x86_64; `flutter build windows` cannot
be cross-compiled and requires a Windows host with Visual Studio
2022's C++ Desktop workload. This commit adds the instructions for
producing the Windows v0.2.0-beta.1 Internal Beta build on an Azure
VM, plus a PowerShell helper that automates the build itself.

docs/release/windows-build.md (v0.1.0):
  - Toolchain pin table (Windows Server 2022, VS 2022 Build Tools
    + C++ workload, Flutter 3.41.9, Rust 1.95 stable, FRB 2.12.0,
    CMake, audiopus build dependency).
  - Azure VM provisioning recipe: Standard_D4s_v5 (4 vCPU / 16 GiB),
    Premium SSD 128 GiB, RDP locked to caller IP, auto-shutdown,
    cost estimate (<USD 1 per build session).
  - Step-by-step PowerShell to install VS 2022 Build Tools with the
    required components, Git for Windows, rustup, Flutter SDK,
    flutter_rust_bridge_codegen, and CMake.
  - Two upload paths for source: temporary git remote OR zip archive
    over RDP clipboard.
  - flutter create --platforms=windows to scaffold the
    windows/ platform folder (the product Flutter app was created
    with only linux + android).
  - cargo build -p chanora_bridge to produce chanora_bridge.dll.
  - flutter build windows --release to produce chanora_flutter.exe
    and the bundle.
  - Drop the DLL next to the EXE so dart:ffi loads it.
  - Smoke-test instructions including the cn.teamspeak.app UDP 9987
    egress gotcha for some Azure regions.
  - Packaging into chanora-v0.2.0-beta.1-windows-x64.zip.
  - Known-issue / caveat table.
  - Reproducibility note (build is not bit-reproducible in this Beta).

tools/build-windows.ps1:
  - Parameter switches: -SkipRustBuild, -RegenerateBindings, -Version.
  - Verifies flutter, cargo, rustc, cmake, git on PATH.
  - Adds the x86_64-pc-windows-msvc target via rustup if missing.
  - Runs flutter create --platforms=windows if the windows/ folder
    is absent in apps/chanora_flutter/.
  - Optionally regenerates FRB bindings.
  - cargo build --release -p chanora_bridge --target x86_64-pc-windows-msvc.
  - flutter pub get + flutter build windows --release.
  - Copies the DLL into the Release bundle.
  - Compress-Archive into chanora-<version>-windows-x64.zip.
  - Prints final artefact paths.

This is documentation + helper only; no actual Windows binaries are
produced by this commit. To produce the binaries, follow §3-§13 of
docs/release/windows-build.md on a Windows host.
2026-05-14 23:02:56 +08:00

144 lines
5.6 KiB
PowerShell

# Chanora Windows build helper.
#
# Run this from an elevated PowerShell on a Windows host that has
# already completed §4 of `docs/release/windows-build.md`:
# - Visual Studio 2022 Build Tools with the C++ Desktop workload
# - Rust stable (x86_64-pc-windows-msvc target)
# - Flutter 3.41.9 stable on PATH
# - flutter_rust_bridge_codegen 2.12.0 (only needed if regenerating bindings)
# - CMake on PATH
#
# Usage (from the repo root C:\chanora):
# .\tools\build-windows.ps1
# .\tools\build-windows.ps1 -SkipRustBuild # if target/ is cached and unchanged
# .\tools\build-windows.ps1 -RegenerateBindings # if you changed bridge API
#
# Produces:
# target\release\chanora_bridge.dll
# apps\chanora_flutter\build\windows\x64\runner\Release\chanora_flutter.exe
# apps\chanora_flutter\build\windows\x64\runner\Release\chanora_bridge.dll (copied)
# chanora-<version>-windows-x64.zip (release bundle)
[CmdletBinding()]
param(
[switch]$SkipRustBuild,
[switch]$RegenerateBindings,
[string]$Version = 'v0.2.0-beta.1'
)
$ErrorActionPreference = 'Stop'
$repoRoot = (Resolve-Path "$PSScriptRoot\..").Path
Set-Location $repoRoot
Write-Host ('=' * 72) -ForegroundColor Cyan
Write-Host "Chanora Windows build" -ForegroundColor Cyan
Write-Host "Repo root : $repoRoot"
Write-Host "Version : $Version"
Write-Host ('=' * 72) -ForegroundColor Cyan
function Assert-Tool {
param([string]$Name, [string]$VersionFlag = '--version')
$cmd = Get-Command $Name -ErrorAction SilentlyContinue
if (-not $cmd) {
throw "Required tool not on PATH: $Name. See docs/release/windows-build.md §4."
}
$ver = & $Name $VersionFlag 2>&1 | Select-Object -First 1
Write-Host " $Name : $ver"
}
Write-Host "`n[1/6] Verify toolchain" -ForegroundColor Yellow
Assert-Tool flutter
Assert-Tool cargo
Assert-Tool rustc
Assert-Tool cmake
Assert-Tool git
# Ensure the Windows target is installed.
$targets = & rustup target list --installed 2>&1
if ($targets -notmatch 'x86_64-pc-windows-msvc') {
Write-Host " Adding rustup target x86_64-pc-windows-msvc..."
rustup target add x86_64-pc-windows-msvc
}
# ---------- 2. Add the Windows platform if missing ----------
$flutterApp = Join-Path $repoRoot 'apps\chanora_flutter'
$winFolder = Join-Path $flutterApp 'windows'
if (-not (Test-Path $winFolder)) {
Write-Host "`n[2/6] Add Windows platform to apps\chanora_flutter" -ForegroundColor Yellow
Push-Location $flutterApp
& flutter create --platforms=windows .
if ($LASTEXITCODE -ne 0) { throw 'flutter create --platforms=windows failed' }
Pop-Location
} else {
Write-Host "`n[2/6] Windows platform already present in apps\chanora_flutter" -ForegroundColor Yellow
}
# ---------- 3. (Optional) Regenerate FRB bindings ----------
if ($RegenerateBindings) {
Write-Host "`n[3/6] Regenerate flutter_rust_bridge bindings" -ForegroundColor Yellow
Assert-Tool flutter_rust_bridge_codegen
& flutter_rust_bridge_codegen generate
if ($LASTEXITCODE -ne 0) { throw 'flutter_rust_bridge_codegen generate failed' }
} else {
Write-Host "`n[3/6] Skipping FRB codegen (use -RegenerateBindings if api.rs changed)" -ForegroundColor Yellow
}
# ---------- 4. Build the Rust cdylib for x86_64-pc-windows-msvc ----------
if (-not $SkipRustBuild) {
Write-Host "`n[4/6] cargo build --release -p chanora_bridge" -ForegroundColor Yellow
& cargo build --release -p chanora_bridge --target x86_64-pc-windows-msvc
if ($LASTEXITCODE -ne 0) { throw 'cargo build chanora_bridge failed' }
} else {
Write-Host "`n[4/6] Skipping Rust build" -ForegroundColor Yellow
}
$bridgeDll = Join-Path $repoRoot 'target\x86_64-pc-windows-msvc\release\chanora_bridge.dll'
if (-not (Test-Path $bridgeDll)) {
# Fallback to host triple if --target wasn't explicit elsewhere.
$bridgeDll = Join-Path $repoRoot 'target\release\chanora_bridge.dll'
}
if (-not (Test-Path $bridgeDll)) {
throw "Bridge DLL not found at $bridgeDll. Check cargo build output."
}
Write-Host " Bridge DLL: $bridgeDll"
# ---------- 5. flutter build windows --release ----------
Write-Host "`n[5/6] flutter build windows --release" -ForegroundColor Yellow
Push-Location $flutterApp
& flutter pub get
if ($LASTEXITCODE -ne 0) { throw 'flutter pub get failed' }
& flutter build windows --release
if ($LASTEXITCODE -ne 0) { throw 'flutter build windows failed' }
Pop-Location
$releaseDir = Join-Path $flutterApp 'build\windows\x64\runner\Release'
$exe = Join-Path $releaseDir 'chanora_flutter.exe'
if (-not (Test-Path $exe)) {
throw "Expected EXE not found at $exe"
}
# Drop the bridge DLL next to the EXE so dart:ffi finds it.
Copy-Item $bridgeDll $releaseDir -Force
Write-Host " Bundle dir : $releaseDir"
Write-Host " EXE : $exe"
Write-Host " Bridge DLL : $(Join-Path $releaseDir 'chanora_bridge.dll')"
# ---------- 6. Package the bundle ----------
Write-Host "`n[6/6] Package release zip" -ForegroundColor Yellow
$zipName = "chanora-$Version-windows-x64.zip"
$zipPath = Join-Path $repoRoot $zipName
if (Test-Path $zipPath) { Remove-Item $zipPath -Force }
Compress-Archive -Path (Join-Path $releaseDir '*') -DestinationPath $zipPath
$zipInfo = Get-Item $zipPath
Write-Host " Zip : $($zipInfo.FullName)"
Write-Host " Size : $([math]::Round($zipInfo.Length / 1MB, 1)) MiB"
Write-Host "`n$('=' * 72)" -ForegroundColor Green
Write-Host "Build complete." -ForegroundColor Green
Write-Host "$('=' * 72)" -ForegroundColor Green
Write-Host "Artefacts:"
Write-Host " EXE : $exe"
Write-Host " Bridge DLL : $(Join-Path $releaseDir 'chanora_bridge.dll')"
Write-Host " Bundle dir : $releaseDir"
Write-Host " Zip : $zipPath"