Files
chanora/docs/release/windows-build.md
T
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

515 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Building Chanora v0.2.0-beta.1 on Windows via Azure VM
**Document type:** Release / Platform Build Instructions
**Version:** 0.1.0
**Status:** Draft
**Language:** English
**Product:** Chanora
**Repo path:** `docs/release/windows-build.md`
---
## 1. Purpose
This document gives exact step-by-step instructions for building the
Chanora `v0.2.0-beta.1` Internal Beta on a Windows host, using an
Azure Virtual Machine. It exists because the development host is
Linux; `flutter build windows` requires a Windows host with Visual
Studio 2022 and cannot be cross-compiled.
After following this doc you will have:
- `chanora_flutter.exe` — the Windows desktop binary.
- `chanora_bridge.dll` — the Rust cdylib loaded by the .exe via FFI.
- A complete release bundle directory the app needs at runtime.
The doc assumes you have:
- An Azure subscription with permission to create VMs.
- An RDP client (Windows: built-in; macOS: Microsoft Remote Desktop;
Linux: `remmina` or `rdesktop`).
- The Chanora source code locally (this repository).
---
## 2. Toolchain versions pinned for this build
| Tool | Version | Why |
|---|---|---|
| Windows Server | 2022 Datacenter | LTS, plenty of Azure images, ships PowerShell 5.1 + Server Core APIs |
| Visual Studio 2022 | Build Tools (Community works too) | Required by `flutter build windows`; provides MSVC, Windows SDK, CMake, link.exe |
| Visual Studio workload | "Desktop development with C++" | Provides MSVC v143, Windows 10/11 SDK, CMake tools, C++ ATL |
| Flutter SDK | 3.41.9 stable | Matches the Linux/Beta build; bridge codegen is version-sensitive |
| Dart SDK | 3.11.5 | Comes with Flutter 3.41.9 |
| Rust toolchain | stable 1.95 (or newer) | Workspace `rust-version = "1.95"` |
| Rust target | `x86_64-pc-windows-msvc` | Native Windows ABI; produces MSVC-compatible .dll |
| `cargo-ndk` | N/A | Not needed for Windows; only Android needs it |
| Opus library | bundled via `audiopus_sys` build script + cmake | On Windows there is no system libopus by default; we build it from source |
| Git for Windows | latest | Convenient `git` + the bundled Bash for running `flutter` if needed |
| 7-Zip (optional) | latest | Convenient for unpacking the source bundle if you uploaded it as zip |
---
## 3. Azure VM provisioning
### 3.1 Recommended SKU
| Setting | Value | Rationale |
|---|---|---|
| Image | `Windows Server 2022 Datacenter — x64 Gen2` | Most common LTS Windows image |
| Size | `Standard_D4s_v5` (4 vCPU, 16 GiB) or larger | The Cargo cold build pulls hundreds of crates; 4 cores keeps the build under 30 minutes |
| OS disk | Premium SSD 128 GiB | Default 128 GiB is enough for VS 2022 (~10 GiB), Flutter SDK (~2 GiB), Rust toolchain (~1 GiB), source + build artefacts (~15 GiB) |
| Auth | Password (you'll RDP in) | Sufficient for a short-lived build VM |
| Inbound port rules | Allow **RDP (3389)** only from your IP | Lock RDP to your IP via NSG; never open to 0.0.0.0/0 |
| Networking | New VNet + public IP | Standard for an ad-hoc build host |
| Auto-shutdown | Enable, 19:00 local time | Stops you forgetting and burning hours |
### 3.2 Estimated cost
`Standard_D4s_v5` in West US 2 is about **USD $0.20/hour** for the
compute plus ~USD $0.01/hour for the disk. A first cold build
(provision → install everything → compile → archive) is typically
23 hours. Total: under **USD $1** per build session if you
deallocate after.
> **Cost gotcha:** *Stopped (deallocated)* VMs do not bill for
> compute; *Stopped* (in the OS shutdown sense, but not deallocated
> in Azure) still bills compute. Always check the Azure portal shows
> the VM as **Stopped (deallocated)**.
### 3.3 Provisioning checklist
1. Azure Portal → **Create a resource****Windows Server 2022 Datacenter (x64 Gen2)**.
2. Choose region near you.
3. Size: `Standard_D4s_v5`.
4. Administrator account: pick a username (e.g. `chanora`) + a strong
password.
5. Inbound ports: RDP only, **restricted to your public IP**.
6. Disks: keep Premium SSD 128 GiB.
7. Networking: defaults; ensure auto-assign public IP.
8. Management → Auto-shutdown: **On**, time = end of your work day,
notification = email.
9. Review + create.
### 3.4 First RDP login
1. Get the VM's public IP from the Azure portal.
2. RDP in as `chanora` / your password.
3. (Optional) Open Server Manager → Local Server → IE Enhanced
Security Configuration → turn **Off** for Administrators so the
downloads in §4 don't get blocked.
---
## 4. Install the toolchain (one-time per VM)
Run all of these in an **elevated PowerShell** (right-click PowerShell → Run as Administrator).
### 4.1 Visual Studio 2022 Build Tools + workload
```powershell
# Download the VS 2022 Build Tools bootstrapper
Invoke-WebRequest -Uri 'https://aka.ms/vs/17/release/vs_buildtools.exe' `
-OutFile "$env:TEMP\vs_buildtools.exe"
# Install with the C++ desktop workload (this is what Flutter requires).
# --quiet suppresses UI; --wait blocks until done; takes 10-15 minutes.
& "$env:TEMP\vs_buildtools.exe" --quiet --wait --norestart `
--add Microsoft.VisualStudio.Workload.VCTools `
--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
--add Microsoft.VisualStudio.Component.Windows11SDK.22621 `
--add Microsoft.VisualStudio.Component.VC.CMake.Project `
--add Microsoft.VisualStudio.Component.VC.ATL `
--includeRecommended
```
When this completes, **reboot the VM** (Visual Studio Build Tools
needs it for environment variables).
### 4.2 Git for Windows
```powershell
winget install --id Git.Git --silent --accept-source-agreements --accept-package-agreements
```
### 4.3 Rust (stable, with the MSVC target)
```powershell
# Download rustup-init for Windows.
Invoke-WebRequest -Uri 'https://win.rustup.rs/x86_64' `
-OutFile "$env:TEMP\rustup-init.exe"
# Install the default toolchain (stable-x86_64-pc-windows-msvc).
& "$env:TEMP\rustup-init.exe" -y --default-toolchain stable --profile minimal
# Open a NEW PowerShell so PATH picks up cargo.
# Then verify:
cargo --version
rustc --version
```
Expected output: `cargo 1.95.0` (or newer), `rustc 1.95.0`. The
default target on Windows is `x86_64-pc-windows-msvc` — this is what
we want.
### 4.4 Flutter SDK (pinned to 3.41.9 stable)
```powershell
# Download Flutter SDK
$flutter = 'https://storage.googleapis.com/flutter_infra_release/releases/stable/windows/flutter_windows_3.41.9-stable.zip'
Invoke-WebRequest -Uri $flutter -OutFile "$env:TEMP\flutter.zip"
Expand-Archive "$env:TEMP\flutter.zip" -DestinationPath 'C:\'
# Add to PATH for the current user (persists across sessions).
[Environment]::SetEnvironmentVariable(
'Path',
[Environment]::GetEnvironmentVariable('Path', 'User') + ';C:\flutter\bin',
'User'
)
# Open a NEW PowerShell so PATH applies, then:
flutter --version
flutter doctor
```
`flutter doctor` should show green on:
- ✓ Flutter (Channel stable, 3.41.9, on Microsoft Windows …)
- ✓ Windows Version (Windows … 10.0.20348 or later)
- ✓ Visual Studio - develop Windows apps (Visual Studio Build Tools 2022 …)
Yellow on Android Studio / Chrome is fine — we're only building
Windows.
### 4.5 `flutter_rust_bridge_codegen` and Dart deps
```powershell
cargo install flutter_rust_bridge_codegen --version "=2.12.0"
```
Takes ~5 minutes (compiles `flutter_rust_bridge_codegen` from source).
### 4.6 Opus build dependency
The `audiopus` Rust crate wraps the C Opus library. On Windows there
is no system Opus, so the `audiopus_sys` build script will attempt to
build Opus from source via CMake (which the VS workload already
provided). No extra action is required — but verify CMake is on
PATH:
```powershell
cmake --version
```
Expected: `cmake version 3.x` (any 3.x ≥ 3.18 is fine).
If CMake is not found, install it explicitly:
```powershell
winget install --id Kitware.CMake --silent
```
---
## 5. Get the source onto the VM
Two options. Pick whichever is easier for you.
### Option A — Push the repo to a temporary git remote
On the Linux host where the repo lives:
```bash
# E.g. create a private GitHub repo and push:
git remote add origin https://github.com/<your-user>/chanora.git
git push --all
git push --tags
```
Then on the Windows VM:
```powershell
cd C:\
git clone https://github.com/<your-user>/chanora.git
cd chanora
git checkout v0.2.0-beta.1
```
### Option B — Upload the source as a zip via RDP clipboard
On Linux:
```bash
cd /home/milkice
git -C chanora archive --format=zip --output=/tmp/chanora-v0.2.0-beta.1.zip v0.2.0-beta.1
```
Copy `/tmp/chanora-v0.2.0-beta.1.zip` into the RDP session
(clipboard or shared drive), unzip into `C:\chanora\`.
Either way, you end up with the working tree at `C:\chanora\`,
checked out at the `v0.2.0-beta.1` tag.
---
## 6. Add the Windows platform to the Flutter app
The product Flutter app was created with `--platforms=linux,android`,
so the `windows/` platform folder does not yet exist. Add it once on
the build VM:
```powershell
cd C:\chanora\apps\chanora_flutter
flutter create --platforms=windows .
```
This creates `apps/chanora_flutter/windows/` containing:
```
windows/
CMakeLists.txt
flutter/
CMakeLists.txt
generated_plugin_registrant.cc
...
runner/
main.cpp
Runner.rc
chanora_flutter.exe.manifest
...
```
> **Important:** Do **not** commit this `windows/` folder back to the
> repo from the VM unless you also do the corresponding edits the
> source-of-truth host uses (icon, manifest, etc.). For Beta it is
> fine to keep it VM-only.
---
## 7. Build the Rust cdylib for Windows
```powershell
cd C:\chanora
cargo build --release -p chanora_bridge
```
This builds the workspace, including:
- The whole `tsclientlib` git dependency tree (slow first time —
expect ~510 minutes for the first compile of `audiopus_sys` +
`tsproto` etc.).
- `chanora_bridge` as a `cdylib` + `staticlib` + `rlib`.
Expected output location:
```
C:\chanora\target\release\chanora_bridge.dll
```
(Note: no `lib` prefix on Windows MSVC.)
Verify:
```powershell
Get-Item C:\chanora\target\release\chanora_bridge.dll | Format-List Name, Length, LastWriteTime
```
The DLL is typically ~1618 MiB.
---
## 8. Regenerate the FRB bindings (optional — only if you changed the bridge API)
The Linux build already produced `lib/src/rust/*.dart` and
`crates/chanora_bridge/src/frb_generated.rs`. The bindings are
platform-agnostic Dart + Rust source, so **they do not need
regenerating on Windows**. Skip §8 unless you modified
`crates/chanora_bridge/src/api.rs` after `v0.2.0-beta.1`.
If you do need to regenerate:
```powershell
cd C:\chanora
flutter_rust_bridge_codegen generate
```
Takes ~510 minutes the first time on Windows.
---
## 9. Build the Flutter Windows binary
```powershell
cd C:\chanora\apps\chanora_flutter
flutter pub get
flutter build windows --release
```
`flutter build windows`:
1. Invokes CMake on `apps/chanora_flutter/windows/`.
2. Builds `chanora_flutter.exe` via MSVC.
3. Bundles the Flutter engine DLL (`flutter_windows.dll`), ICU data,
Dart-AOT-compiled `app.so` (delivered as `data\app.so`), the
Flutter `data\` directory, and platform-specific resources.
Build time: ~35 minutes on `Standard_D4s_v5` once dependencies are
cached.
Expected output location:
```
C:\chanora\apps\chanora_flutter\build\windows\x64\runner\Release\
```
Contents:
| File | Size (approx) | Notes |
|---|---|---|
| `chanora_flutter.exe` | ~10 MiB | The launcher .exe |
| `flutter_windows.dll` | ~17 MiB | Flutter engine |
| `data\icudtl.dat` | ~10 MiB | Unicode tables |
| `data\app.so` | varies | AOT-compiled Dart code |
| `data\flutter_assets\` | varies | Images, fonts, ARB-derived .json |
---
## 10. Add the Rust DLL to the bundle
The Flutter app loads `chanora_bridge.dll` at runtime via `dart:ffi`.
Drop the DLL next to the .exe (the same directory):
```powershell
$src = 'C:\chanora\target\release\chanora_bridge.dll'
$dst = 'C:\chanora\apps\chanora_flutter\build\windows\x64\runner\Release\'
Copy-Item $src $dst -Force
```
Verify everything is in place:
```powershell
Get-ChildItem $dst -Recurse | Select-Object FullName, Length |
Format-Table -AutoSize
```
You should see:
```
C:\chanora\apps\chanora_flutter\build\windows\x64\runner\Release\chanora_flutter.exe
C:\chanora\apps\chanora_flutter\build\windows\x64\runner\Release\chanora_bridge.dll
C:\chanora\apps\chanora_flutter\build\windows\x64\runner\Release\flutter_windows.dll
C:\chanora\apps\chanora_flutter\build\windows\x64\runner\Release\data\app.so
C:\chanora\apps\chanora_flutter\build\windows\x64\runner\Release\data\icudtl.dat
C:\chanora\apps\chanora_flutter\build\windows\x64\runner\Release\data\flutter_assets\...
```
---
## 11. Smoke test on the VM
Double-click `chanora_flutter.exe` (or `& '...\chanora_flutter.exe'`
in PowerShell). The Beta UI should appear:
- Banner: "Beta build — voice in/out wired; not production ready."
- Form: `cn.teamspeak.app` + `ChanoraBeta` pre-populated.
- Connect button.
Press **Connect** → after a few seconds you should see the channel
tree of `cn.teamspeak.app` (Vigorous Pro). Press **Start audio**
PTT button appears. Hold it to transmit (a Windows mic permission
prompt may appear).
> **Network gotcha:** Some Azure regions block UDP 9987 outbound by
> default. If Connect times out, check the VM's NSG (outbound rules)
> and the regional firewall.
---
## 12. Package the release artefact
```powershell
$src = 'C:\chanora\apps\chanora_flutter\build\windows\x64\runner\Release'
$out = 'C:\chanora-v0.2.0-beta.1-windows-x64.zip'
Compress-Archive -Path "$src\*" -DestinationPath $out -Force
Get-Item $out | Format-List Name, Length
```
Expected size: ~5080 MiB.
---
## 13. Download to your local host
From your local machine (Linux/macOS/Windows):
```bash
# Use Azure CLI to copy via SAS, or just RDP the file out.
# Simplest: in the RDP session enable clipboard file transfer
# (mstsc /control or Remmina's "share local folder"), then drag the
# zip out.
```
Or use Azure Blob Storage if you want versioned hosting.
---
## 14. Final artefact paths (what you actually produce)
Inside the VM, after a successful build:
| Artefact | Path on the VM |
|---|---|
| Bridge DLL | `C:\chanora\target\release\chanora_bridge.dll` |
| Flutter EXE | `C:\chanora\apps\chanora_flutter\build\windows\x64\runner\Release\chanora_flutter.exe` |
| Complete runtime bundle | `C:\chanora\apps\chanora_flutter\build\windows\x64\runner\Release\` |
| Release zip | `C:\chanora-v0.2.0-beta.1-windows-x64.zip` |
---
## 15. After the build — deallocate the VM
```powershell
# In the Azure CLI on your local host, OR via the portal:
az vm deallocate --resource-group <rg> --name <vm-name>
```
Verify the portal says **Stopped (deallocated)**.
---
## 16. Known issues and caveats
| Issue | Workaround |
|---|---|
| `audiopus_sys` build fails with "cmake not found" | Re-run §4.6's `winget install Kitware.CMake` and open a new PowerShell. |
| `flutter build windows` complains about Long Paths | `Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name LongPathsEnabled -Value 1`, then reboot. |
| Microsoft Defender quarantines `chanora_bridge.dll` | Add `C:\chanora\target\release\` to Defender exclusions before the cargo build. |
| The build VM cannot reach `cn.teamspeak.app` on UDP 9987 | Confirm Azure regional firewall allows outbound UDP. The Linux dev host's verification doesn't translate to Azure VMs automatically. |
| First `cargo build` takes > 30 minutes | Normal. Subsequent builds reuse `target/` and are ~1 minute. |
| `flutter pub get` fails behind a corporate proxy | Set `HTTPS_PROXY` and `HTTP_PROXY` environment variables before running. |
| The `windows/` folder created by `flutter create` is missing icons | Replace `windows\runner\resources\app_icon.ico` with a Chanora icon. The default Flutter icon ships otherwise. Cosmetic only for Beta. |
---
## 17. Reproducibility note
This build process is **not bit-reproducible** on Windows in the
current state:
- The `audiopus_sys` build script picks the CMake-discovered MSVC
toolchain, which embeds its version into the DLL.
- Dart AOT compilation embeds a Dart kernel hash.
- Windows resource compilation embeds a build timestamp.
If true reproducibility is required for a future External Beta or
MVP Public release, that is Beta+ work; the build above is
sufficient for an Internal Beta milestone per DEC-001.
---
## 18. Change History
| Version | Date | Description |
|---|---|---|
| 0.1.0 | 2026-05-14 | Initial Windows build instructions for Chanora `v0.2.0-beta.1`. Targets Azure VM `Standard_D4s_v5` running Windows Server 2022, Visual Studio 2022 Build Tools with the C++ desktop workload, Rust 1.95 stable (`x86_64-pc-windows-msvc`), Flutter 3.41.9 stable, `flutter_rust_bridge` 2.12.0. Produces `chanora_flutter.exe` + `chanora_bridge.dll` packaged into `chanora-v0.2.0-beta.1-windows-x64.zip`. |