Two adjustments after the Android boot investigation
(cf. AGENTS.md section 'PostIt.Android boot crash sur AVD
x86_64 : investigation par couches'):
- Avalonia 12.0.4 -> 12.1.1 in PostIt/Directory.Packages.props.
12.1.x is the current Avalonia 12 stable line; 12.0.4 had a
known WindowingPlatformStub regression on Pixel x86_64 AVDs
(issue AvaloniaUI/Avalonia#18459 family). 12.1.1 does not
actually fix the layer-3 NotSupportedException on this
specific Pixel + Android 16 + x86_64 combination (verified
by rebuild + logcat capture on 2026-08-22), but staying on
12.0.4 forever is wrong, and 12.1.1 is the baseline most
users are on. The Makefile qemu-build already passes
-p:EmbedAssembliesIntoApk=true and -p:RuntimeIdentifier=
android-x64 to work around the Fast Deployment / AOT issues.
- qemu-logcat-boot LOGCAT_BOOT_WAIT 15s -> 30s. The crash
reproduces well under 5s, so the wait value is moot for
diagnosis, but 30s gives a wider margin when the runtime
happens to be slow to JIT (boot tries to draw a frame in
texture-pass scenarios). Override on the command line is
unchanged: 'make qemu-logcat-boot LOGCAT_BOOT_WAIT=N'.
No MAUI change: Microsoft.Maui.Essentials was deliberately
unhooked during a hypothesis check and put back to keep the
contact-flow code path stable. The MAUI removal made no
difference to the crash (verified).
The qemu install path used to crash on startup with
'No assemblies found in files/.__override__/<rid>':
monodroid-glue.cc:757 / SIGABRT. Root cause: the .NET 10 Android
SDK defaults to Fast Deployment in Debug, which ships the APK
without managed assemblies and pushes them at runtime via adb —
not viable on the qemu emulator.
Fix:
- Replace the no-op -p:AndroidEnableFastDeployment=false flag
(does not exist as an MSBuild property in the .NET 10 SDK) with
-p:EmbedAssembliesIntoApk=true, which forces the build to
cross-compile the managed assemblies into native lib_*.dll.so
libraries for every ABI and pack them into the APK under
lib/<arch>/. The Mono runtime then loads them directly,
bypassing the Fast Deployment code path entirely.
- Add CONFIG variable passthrough so 'make qemu-install CONFIG=Release'
builds an optimised APK for release smoke tests.
- qemu-build now consumes $(CONFIG) instead of hardcoded 'Debug'
for the APK output path.
Side effect: the Debug APK balloons from ~13 MB (libs only) to
~160 MB (libs + AOT-compiled assemblies for all four supported
ABIs). That is acceptable for the local qemu install path; the
Forgejo release workflow builds Release APKs separately and is
unaffected.
Validated end-to-end on this machine: AVD boots in 109s, the
build produces an APK with lib_*.dll.so for x86_64 (125 MB),
uninstall + reinstall + am start no longer aborts at
monodroid-glue.cc:757 (next test will confirm the app actually
renders, this commit only fixes the Fast Deployment crash).
Also adds qemu-logcat-boot target from the previous edit
(unchanged, documented in this commit message for context).
Targets for building and installing PostIt.Android (Debug) on the
local postit_test_avd AVD without leaving the terminal:
make qemu # run AVD -> wait boot -> build APK -> install
make qemu-install # (re)build APK + install (AVD must be running)
make qemu-build # build APK alone (no install)
make qemu-run # start the AVD in the background
make qemu-wait-boot # block until sys.boot_completed=1 (180s timeout)
make qemu-stop # adb emu kill
Defaults match the local setup: AVD postit_test_avd on x86_64
(android-x64 RID), adb on emulator-5554, Android SDK at
/opt/android-sdk. All overridable on the command line:
make qemu POSTIT_RID=android-arm64 ADB_SERIAL=emulator-5556
EMU_HEADLESS=1 disables the emulator window for scripted runs.
qemu-run logs to /tmp/yavsc-emu/<avd>.log.
Validated end-to-end on this machine: AVD booted in 109s on a
loaded system, APK built and installed cleanly. The 'UI not
responsive' warning is the software-rendering fallback when KVM
is busy; it does not block the install.
Paul wanted a Makefile target that:
- takes the target version as an argument (V=1.0.7-rc1),
- creates a release/<V> branch from main,
- runs 'dotnet-gitversion /updateprojectfiles' to bump
<Version> across all .csproj from git history,
- commits the bump on the release branch (not on main, so
main stays clean),
- pushes the new branch to origin.
The /src/**/*.csproj paths and CHANGELOG.md are excluded from
Forgejo's protected-branch rule so the bump commit goes
through on the release branch.
The target refuses to run unless the operator is already on
main with a clean working tree — no automatic checkout to
main, so the bump never lands on the wrong branch by
accident.
The version in the branch name (V=...) is an intent label.
The version GitVersion writes into the .csproj is whatever
GitVersion computes from git history (last tag + commit
count), so assembly versions stay truthful even when the
branch name is aspirational.