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.
This commit is contained in:
@@ -0,0 +1,514 @@
|
||||
# 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
|
||||
2–3 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 ~5–10 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 ~16–18 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 ~5–10 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: ~3–5 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: ~50–80 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`. |
|
||||
@@ -0,0 +1,143 @@
|
||||
# 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"
|
||||
Reference in New Issue
Block a user