NetDesk 1.5.0 — source release
This commit is contained in:
commit
40318aafdd
227 files changed
+80798
No files matched your search
@@ -0,0 +1,180 @@
|
||||
# Building NetDesk for Android
|
||||
|
||||
NetDesk's Android app is a Flutter UI (`ui/`) bound, through
|
||||
[flutter_rust_bridge](https://cjycode.com/flutter_rust_bridge/) (FRB v2), to a
|
||||
compiled Rust library. The Rust FFI layer is the **`netdesk-frb`** crate
|
||||
(`frb/`), a `cdylib` that statically links **`netdesk-core`** (signaling, E2E
|
||||
crypto, transport, H.264 decode). On Android the library ships inside the
|
||||
APK/AAB as `lib/<abi>/libnetdesk_frb.so` and the Dart side `dlopen`s it (the FRB
|
||||
loader looks for the stem `netdesk_frb`).
|
||||
|
||||
```
|
||||
netdesk-frb (+ netdesk-core) --cargo-ndk--> ui/android/app/src/main/jniLibs/<abi>/libnetdesk_frb.so
|
||||
Flutter (ui/) --gradle-----> release .apk / split .apk / .aab (signed)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## The one command
|
||||
|
||||
From the repo root (`netdesk-native/`), in a shell whose `PATH` contains the
|
||||
MinGW tools, cargo, and Flutter:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File packaging\build-android.ps1
|
||||
```
|
||||
|
||||
That single command:
|
||||
|
||||
1. verifies / auto-provisions the toolchain (cargo-ndk, the rustup Android
|
||||
targets),
|
||||
2. detects the Android NDK at `C:\dev\android-ndk`,
|
||||
3. compiles `netdesk-frb` for **arm64-v8a, armeabi-v7a, x86_64** with cargo-ndk
|
||||
and drops `libnetdesk_frb.so` straight into
|
||||
`ui/android/app/src/main/jniLibs/<abi>/`,
|
||||
4. builds the release **fat APK**, the **per-ABI split APKs**, and the Play
|
||||
**App Bundle (.aab)**.
|
||||
|
||||
Useful switches:
|
||||
|
||||
| Switch | Effect |
|
||||
| --- | --- |
|
||||
| `-Target apk\|split\|aab\|rust\|all` | Build only that deliverable (default `all`; `rust` = just the `.so`). |
|
||||
| `-SkipRust` | Reuse the `.so` already in `jniLibs`, build Flutter only. |
|
||||
| `-Abis arm64-v8a` | Restrict the ABIs (default all three). |
|
||||
| `-GenerateKeystore` | Create the release keystore + `key.properties` first (see below). |
|
||||
| `-MinSdk 21` | Android API the `.so` links against (must be `<=` Flutter `minSdk`). |
|
||||
| `-NdkHome <path>` | Override the NDK location (default `C:\dev\android-ndk`). |
|
||||
|
||||
---
|
||||
|
||||
## Toolchain
|
||||
|
||||
| Component | Version / location used here |
|
||||
| --- | --- |
|
||||
| Rust | stable (cargo 1.99) on `PATH` |
|
||||
| rustup targets | `aarch64-linux-android`, `armv7-linux-androideabi`, `x86_64-linux-android` |
|
||||
| cargo-ndk | 4.1.2 (`cargo install cargo-ndk`) |
|
||||
| Android NDK | r26d (`26.3.11579264`) at `C:\dev\android-ndk` (`ANDROID_NDK_HOME`) |
|
||||
| Android SDK | `%LOCALAPPDATA%\Android\Sdk` |
|
||||
| Flutter | `C:\dev\flutter\bin\flutter.bat` |
|
||||
| JDK (keytool + Gradle) | Android Studio JBR (auto-detected) |
|
||||
| nasm | on `PATH` (needed by `openh264` for the x86_64 ABI) |
|
||||
|
||||
One-time setup (the build script also does the first three automatically):
|
||||
|
||||
```powershell
|
||||
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android
|
||||
cargo install cargo-ndk
|
||||
# NDK: unzip the Android NDK r26+ to C:\dev\android-ndk (set ANDROID_NDK_HOME)
|
||||
```
|
||||
|
||||
Recommended `PATH` (Git Bash form):
|
||||
|
||||
```bash
|
||||
export PATH="/c/mingw-netdesk/mingw64/bin:$HOME/.cargo/bin:/c/dev/flutter/bin:$PATH"
|
||||
```
|
||||
|
||||
### What cargo-ndk runs
|
||||
|
||||
The Rust step is exactly:
|
||||
|
||||
```
|
||||
cargo ndk -t arm64-v8a -t armeabi-v7a -t x86_64 \
|
||||
-o ui/android/app/src/main/jniLibs --platform 21 \
|
||||
build --release --package netdesk-frb --lib
|
||||
```
|
||||
|
||||
cargo-ndk sets the per-ABI clang/linker from the NDK, and the `-o` flag copies
|
||||
each produced `libnetdesk_frb.so` into `jniLibs/<abi>/`. The `.so` are build
|
||||
artifacts (git-ignored) and are regenerated on every run.
|
||||
|
||||
---
|
||||
|
||||
## Release signing
|
||||
|
||||
Signing credentials live in `ui/android/key.properties`, which is **git-ignored**
|
||||
(so are `*.keystore` / `*.jks`). A committable template is
|
||||
`ui/android/key.properties.example`.
|
||||
|
||||
`app/build.gradle.kts` loads `key.properties` when present and signs the release
|
||||
build with it; when it is absent the release build falls back to **debug**
|
||||
signing so `flutter run --release` still works during development.
|
||||
|
||||
Create the upload keystore once (the password is read from the environment and
|
||||
is **never** written into a committed file):
|
||||
|
||||
```powershell
|
||||
$env:NETDESK_KEYSTORE_PASSWORD = '<your-strong-password>'
|
||||
powershell -ExecutionPolicy Bypass -File packaging\build-android.ps1 -GenerateKeystore
|
||||
```
|
||||
|
||||
This writes:
|
||||
|
||||
* `ui/android/app/netdesk-release.keystore` - RSA 4096, alias `netdesk`, 10000-day validity,
|
||||
* `ui/android/key.properties` - with the alias, store file, and the password you
|
||||
supplied (local only; keep it out of version control).
|
||||
|
||||
> Back up the keystore and remember the password. If you lose either you can no
|
||||
> longer push updates to an app already published under that key (unless it uses
|
||||
> Play App Signing with a separate upload key you can reset).
|
||||
|
||||
---
|
||||
|
||||
## Outputs
|
||||
|
||||
After a full build:
|
||||
|
||||
| Deliverable | Path (under `ui/`) |
|
||||
| --- | --- |
|
||||
| Fat APK (all ABIs) | `build/app/outputs/flutter-apk/app-release.apk` |
|
||||
| Split APKs (per ABI) | `build/app/outputs/flutter-apk/app-arm64-v8a-release.apk`, `-armeabi-v7a-`, `-x86_64-` |
|
||||
| Play App Bundle | `build/app/outputs/bundle/release/app-release.aab` |
|
||||
|
||||
The fat APK is convenient for side-loading / direct download; the split APKs are
|
||||
smaller per device; the `.aab` is what Google Play requires.
|
||||
|
||||
---
|
||||
|
||||
## Publishing to Google Play (AAB)
|
||||
|
||||
1. Produce the signed bundle:
|
||||
|
||||
```powershell
|
||||
powershell -ExecutionPolicy Bypass -File packaging\build-android.ps1 -Target aab
|
||||
```
|
||||
|
||||
(or run the default `all` target). The bundle is
|
||||
`ui/build/app/outputs/bundle/release/app-release.aab`.
|
||||
|
||||
2. In the [Play Console](https://play.google.com/console), create the app, then
|
||||
upload the `.aab` under a release track (internal testing first).
|
||||
|
||||
3. Enrol in **Play App Signing** (recommended). Google then holds the *app
|
||||
signing key*; the keystore above becomes your *upload key*. If the upload key
|
||||
is ever compromised you can ask Google to reset it - which is why App Signing
|
||||
is preferred over shipping the raw signing key.
|
||||
|
||||
4. `versionCode` / `versionName` come from `ui/pubspec.yaml`
|
||||
(`version: x.y.z+build`). Bump the `+build` number for every Play upload - the
|
||||
Console rejects a duplicate `versionCode`.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
* **"Android NDK not found"** - the script could not find a complete NDK at
|
||||
`C:\dev\android-ndk` (it checks for `source.properties` +
|
||||
`toolchains\llvm\prebuilt`). Finish extracting the NDK, set `ANDROID_NDK_HOME`,
|
||||
or pass `-NdkHome <path>`. Use `-SkipRust` to build only the Flutter layer
|
||||
against an already-built `.so`.
|
||||
* **x86_64 ABI fails in `openh264`** - that ABI needs `nasm` on `PATH`. arm64-v8a
|
||||
and armeabi-v7a do not. Drop x86_64 with `-Abis arm64-v8a,armeabi-v7a` if you
|
||||
only ship to real devices.
|
||||
* **Gradle wants to download an NDK** - `app/build.gradle.kts` points AGP at
|
||||
`ANDROID_NDK_HOME` when it is set, so the prebuilt (already stripped) `.so` are
|
||||
packaged without a second NDK download. Make sure the env var is set (the build
|
||||
script sets it).
|
||||
* **`UnsatisfiedLinkError: libnetdesk_frb.so`** at runtime - the `.so` for the
|
||||
device's ABI is missing from `jniLibs`. Re-run the Rust step (`-Target rust`)
|
||||
for that ABI, or confirm the FRB loader stem is still `netdesk_frb`.
|
||||
Reference in new issue
Block a user