|
46 | 46 | managed paths (the JIT no longer needs to tier them up at runtime, and Mono's |
47 | 47 | profiled AOT covers framework/game hot loops including draw-thread Schedulers, |
48 | 48 | bindable propagation, and the texture upload path). |
49 | | - * PublishTrimmed stays OFF — re-enabling it requires explicitly rooting every |
50 | | - reflection-using assembly (osu.Game, rulesets, Realm, Newtonsoft.Json, |
51 | | - AutoMapper, Sentry, OsuTK, Microsoft.CSharp, ppy.Veldrid.SPIRV …) and running |
52 | | - with SuppressTrimAnalysisWarnings=false to surface gaps before shipping. That |
53 | | - is a separate, larger PR. |
| 49 | + * PublishTrimmed stays OFF — the .NET ILLink trimmer is driven exclusively |
| 50 | + through AndroidLinkMode=Full + osu.Android/Linker.xml (see below). |
| 51 | + Setting PublishTrimmed=true in addition would double-run ILLink with |
| 52 | + automatic root discovery, re-introducing the risk of silent reflection |
| 53 | + gaps this approach was designed to eliminate. |
| 54 | + * AndroidLinkMode=Full (replacing the previous SdkOnly). Full enables |
| 55 | + ILLink across all assemblies, not just Mono.Android.dll. Compared to |
| 56 | + SdkOnly this additionally strips unused BCL types, ~80% of NUnit bulk, |
| 57 | + and unreachable types in pure-algorithmic utility libs. |
| 58 | + osu.Android/Linker.xml supplies a curated preserve="all" list for every |
| 59 | + assembly that uses runtime reflection — implementing "manual trim": we |
| 60 | + review and own the preserve list rather than letting the trimmer auto- |
| 61 | + discover reflection roots. See Linker.xml for per-assembly rationale. |
| 62 | + When a new reflection-using package is added, add it to Linker.xml. |
54 | 63 | * AndroidEnableMarshalMethods stays OFF (see PropertyGroup above) — silent |
55 | 64 | SIGSEGV with current interop on .NET 10 Android. |
56 | 65 | * Server GC is enabled for Release: workstation GC's STW pauses on the Update/ |
|
60 | 69 | the cost of ~20-30% extra resident memory. Mono Android has supported this |
61 | 70 | since .NET 8; ppy/osu desktop already uses it. Concurrent GC is the .NET |
62 | 71 | default but we set it explicitly so Server GC runs in the background mode |
63 | | - rather than blocking foreground. |
64 | | -
|
65 | | - To re-enable trimming in the future, reintroduce it on its own, root every |
66 | | - reflection-using assembly explicitly, and run with SuppressTrimAnalysisWarnings=false |
67 | | - to surface the gaps before shipping. --> |
| 72 | + rather than blocking foreground. --> |
68 | 73 | <PropertyGroup Condition="'$(Configuration)' == 'Release'"> |
69 | 74 | <!-- Compress managed assemblies inside the APK (LZ4). Android extracts them on first run |
70 | 75 | but the download/APK size is significantly smaller. --> |
|
74 | 79 | <DebugType>none</DebugType> |
75 | 80 | <DebugSymbols>false</DebugSymbols> |
76 | 81 | <!-- Profiled AOT: pre-compile the hot methods listed in the bundled .NET / Android |
77 | | - profiles. Methods outside the profile remain JIT-compiled at runtime. NO trimming — |
78 | | - every method in every assembly stays present, so a profile-miss falls back to JIT |
79 | | - instead of throwing MissingMethodException like the previous trim+AOT combo did. --> |
| 82 | + profiles. Methods outside the profile remain JIT-compiled at runtime. Preserved |
| 83 | + assemblies (see Linker.xml) are fully present, so a profile-miss falls back to JIT |
| 84 | + instead of throwing MissingMethodException. --> |
80 | 85 | <AndroidEnableProfiledAot>true</AndroidEnableProfiledAot> |
81 | 86 | <!-- Concurrent Server GC. Server GC uses per-core allocation contexts and parallel |
82 | 87 | collections to reduce STW pause time, which is the largest source of >1ms frame |
83 | 88 | spikes on the Update/Draw threads. Memory usage rises ~20-30% in exchange. --> |
84 | 89 | <ServerGarbageCollection>true</ServerGarbageCollection> |
85 | 90 | <ConcurrentGarbageCollection>true</ConcurrentGarbageCollection> |
86 | | - <!-- Defensive explicit-set: we rely on the SDK linker to walk only Android SDK types |
87 | | - (NOT user assemblies — see PublishTrimmed=off rationale above). The .NET Android |
88 | | - SDK default is currently 'SdkOnly' but has changed across SDK versions; making it |
89 | | - explicit here pins the behaviour so a future SDK bump cannot silently flip us to |
90 | | - 'Full' linking and break the reflection-heavy code paths in osu.Game / Realm / |
91 | | - Newtonsoft.Json / AutoMapper / Sentry / OsuTK. --> |
92 | | - <AndroidLinkMode>SdkOnly</AndroidLinkMode> |
93 | | - <!-- Defensive explicit-set: keep IL alongside profiled-AOT native code so any method |
94 | | - outside the bundled AOT profile has a JIT fallback (instead of MissingMethodException |
95 | | - at first call). The .NET Android SDK default is 'false' for non-trimmed builds |
96 | | - already, but we make it explicit so a future SDK bump cannot silently start |
97 | | - stripping IL and reproduce the trim-then-AOT crash class we removed above. --> |
| 91 | + <!-- Full mode enables ILLink across all assemblies (not just Mono.Android.dll). |
| 92 | + osu.Android/Linker.xml provides the curated preserve="all" list for every |
| 93 | + assembly that uses runtime reflection, making this "manual trim" rather than |
| 94 | + automatic: the linker strips only what we knowingly leave out of Linker.xml. --> |
| 95 | + <AndroidLinkMode>Full</AndroidLinkMode> |
| 96 | + <!-- Keep IL alongside profiled-AOT native code so any method outside the bundled |
| 97 | + AOT profile has a JIT fallback (instead of MissingMethodException at first |
| 98 | + call). The .NET Android SDK default is 'false' for non-trimmed builds; |
| 99 | + we make it explicit so a future SDK bump cannot silently start stripping IL |
| 100 | + and reproduce the trim-then-AOT crash class we removed above. --> |
98 | 101 | <AndroidStripILAfterAOT>false</AndroidStripILAfterAOT> |
99 | 102 | </PropertyGroup> |
100 | 103 |
|
101 | 104 | <ItemGroup> |
102 | | - <PackageReference Include="ppy.osu.Framework.Android" Version="2026.508.1" /> |
| 105 | + <PackageReference Include="ppy.osu.Framework.Android" Version="2026.508.2" /> |
103 | 106 | <!-- `ppy.osu.Framework.NativeLibs` is a transitive dependency of `ppy.osu.Framework` |
104 | 107 | that ships desktop-only natives (Linux/macOS/Windows) under `runtimes/<rid>/native/` |
105 | 108 | — including a bare Linux `libbass.so`/`libbass_fx.so`/`libbassmix.so` for linux-arm64. |
|
0 commit comments