You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit d52302d
Browse filesBrowse the repository at this point in the historyBrowse files
PIP_FIND_LINKS=/tmp/ci_wheels/findlinks uv run flet build apk # or ios-simulator
106
+
```
107
+
108
+
The example builds for 3.14 (gotcha #2), so the run must include the 3.14 leg. To read the
109
+
app's own output without racing a screenshot against the update, the Flet patch log
110
+
carries every control value: `xcrun simctl spawn "$UDID" log show --last 2m --style compact
111
+
--predicate 'process == "<app-name>"'` (a release APK logs no patches; use screenshots there).
112
+
95
113
### forge slice syntax (quick reference)
96
114
97
115
`android:arm64-v8a` | `android:x86_64` | `android:armeabi-v7a` | `iphonesimulator:arm64` | `iphonesimulator:x86_64` | `iphoneos:arm64` — the first token is the **SDK**, not the OS. `forge iOS:arm64` dies with a raw `KeyError: 'iOS'` (only the bare-platform forms `forge android` / `forge iOS` take the OS name, and those build every arch).
@@ -115,6 +133,12 @@ for i in $(seq 1 30); do grep EXIT "$DATA/Library/Caches/console.log" 2>/dev/nul
115
133
sed -i '''s/hw.ramSize=.*/hw.ramSize=6144/'"$cfg"2>/dev/null ||echo'hw.ramSize=6144'>>"$cfg"
116
134
```
117
135
(`aosp_atd` is rootable but headless — it can't run a Flet GUI app, so don't use it here.)
136
+
If the emulator dies with *"Cannot find AVD system path. Please define ANDROID_SDK_ROOT"*
137
+
(or, with that variable set, *"Broken AVD system path"*), the AVD survived but its system
138
+
image did not (`system-images/` empty) — exporting the variable only changes the message.
139
+
Reinstall the image with the SDK's own sdkmanager; a Homebrew `sdkmanager` first on `PATH`
140
+
installs into its own root, where the emulator never looks:
5.**Give the emulator RAM + disk.** A heavy `.so` (polars ~130 MB) + Python + the Flutter engine OOM-kills the app on a default AVD (`lowmemorykiller: Kill 'com.flet.recipe_tester'`). 6 GB RAM avoids it. The ~100–235 MB APK install needs a big `/data` (6 GB partition); if you hit `INSTALL_FAILED_INSUFFICIENT_STORAGE`, free space (uninstall old apps) or use a fresh AVD.
120
144
@@ -126,7 +150,7 @@ for i in $(seq 1 30); do grep EXIT "$DATA/Library/Caches/console.log" 2>/dev/nul
126
150
127
151
9.**Android `console.log` lives in the app's CACHE dir — `/data/data/com.flet.recipe_tester/cache/console.log` — NOT under `files/flet/app/`** (that's the app code; `python_site_packages` is a SIBLING under `files/flet/`). Polling the wrong dir looks like "the app never wrote a result" and cost ~10 min during the sherpa-onnx validation. Root is still required to read it (gotcha #4): `adb root` then `adb shell cat …`, or `adb shell su 0 cat …` on a google_apis image.
128
152
129
-
10. **`flet build ios-simulator` resolves the `iphoneos` (device) wheel AS WELL as both simulator ones.** It configures pip for `iphoneos.arm64` + `iphonesimulator.arm64` + `iphonesimulator.x86_64` and needs a wheel for EACH — a partial local matrix fails with `No matching distribution found`. Build all three iOS slices first (for the recipe AND every `flet-lib*` host dep). CI never hits this because it dumps all of `dist/*.whl` into its find-links dir. (`flet build apk` needs only the one `--arch` slice — the asymmetry is iOS-only.) Long-standing gotcha; re-hit during the onnxruntime iOS spike. **Worse: serious_python's PER-ARCH native staging (`build/site-packages/<iosarch>/`) resolves those slice wheels from the INDEX directly and does NOT honor `PIP_FIND_LINKS`/dist-test locally** — so a hand-patched `-9999` wheel in your find-links dir is used for the initial pip install but the staged PYTHON code (e.g. `cv2/__init__.py`, whichever slice it picks — often `iphoneos.arm64`) still comes from the published wheel. Net: you cannot validate a *hand-patched loader* on a local `ios-simulator` build; use a real `forge` build of all slices, or verify in CI (where the freshly-built slice wheels ARE used — this is why coolprop iOS passed in CI but a hand-patched opencv wouldn't locally).
153
+
10. **`flet build ios-simulator` resolves the `iphoneos` (device) wheel AS WELL as both simulator ones.** It configures pip for `iphoneos.arm64` + `iphonesimulator.arm64` + `iphonesimulator.x86_64` and needs a wheel for EACH — a partial local matrix fails with `No matching distribution found`. Build all three iOS slices first (for the recipe AND every `flet-lib*` host dep). CI never hits this because it dumps all of `dist/*.whl` into its find-links dir. (`flet build apk` needs only the one `--arch` slice — the asymmetry is iOS-only.) Long-standing gotcha; re-hit during the onnxruntime iOS spike. **Worse: a hand-patched wheel can still lose in serious_python's PER-ARCH native staging (`build/site-packages/<iosarch>/`).** That pip run does read the inherited `PIP_FIND_LINKS` (flet 0.86.5 logs "Looking in links: …", and an unpublished package such as lz4 resolves from it), but during the opencv work a hand-patched `-9999` wheel in the find-links dir was used for the initial pip install while the staged PYTHON code (e.g. `cv2/__init__.py`, whichever slice it picks — often `iphoneos.arm64`) still comes from the published wheel. Net: you cannot validate a *hand-patched loader* on a local `ios-simulator` build; use a real `forge` build of all slices, or verify in CI (where the freshly-built slice wheels ARE used — this is why coolprop iOS passed in CI but a hand-patched opencv wouldn't locally).
130
154
131
155
10a. **Old local Xcode can't compile newer Flutter plugins** — e.g. Xcode 16.4 dies on `device_info_plus` 12.4.0 with `ARC Semantic Issue: No visible @interface for 'NSProcessInfo' declares the selector 'isiOSAppOnVision'` (a visionOS selector added in a newer SDK). This is a LOCAL toolchain gap, not your recipe (CI's Xcode 26.5 is fine). Pin the offending plugins older in the generated app pyproject before `flet build ios-simulator`:
132
156
```toml
@@ -136,17 +160,28 @@ for i in $(seq 1 30); do grep EXIT "$DATA/Library/Caches/console.log" 2>/dev/nul
136
160
```
137
161
(`stage_recipe.sh` regenerates the pyproject, so append this AFTER staging.)
138
162
139
-
10b. **New local Xcode rejects flet's iOS 13.0 deployment target** — Xcode 27 with flet 1.0.3: `Target Integrity (Xcode): The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 13.0, but the range of supported deployment target versions is 15.0 to 27.0.x`. The site-packages staging has already finished at that point, so finish the build by hand in `<app>/build/flutter`:
The `.app` lands in `build/flutter/build/ios/iphonesimulator/`, not `build/ios-simulator/`. CI's older Xcode needs none of this. Used for the xgboost example, 2026-10-04.
182
+
A fresh `flet build` regenerates the template, so repeat the patch after every one.
183
+
The env is flet-cli's `_flutter_path_env` (`build_base.py`); without
184
+
`SERIOUS_PYTHON_BUNDLE_ID` the embedded frameworks get `org.python.*` identifiers.
150
185
151
186
11.**Two booted simulators make `simctl booted` ambiguous.** With more than one sim booted, `simctl install booted …` targets one device and your subsequent `get_app_container booted …` may query the OTHER — the app "isn't installed" / the container is empty despite a successful install. Use the explicit `$UDID` for every simctl call (as the loop above does); never rely on `booted` unless you've verified exactly one device is booted (`xcrun simctl list devices | grep -c Booted`).
0 commit comments