forked from ppy/osu
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathosu.Android.props
More file actions
129 lines (121 loc) · 8.42 KB
/
Copy pathosu.Android.props
File metadata and controls
129 lines (121 loc) · 8.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<Project>
<PropertyGroup>
<SupportedOSPlatformVersion>33.0</SupportedOSPlatformVersion>
<!-- arm64-v8a only. Modern Android devices are 99%+ arm64; 32-bit arm32 (armeabi-v7a)
adds ~200 MB of duplicate native libraries for negligible device coverage.
x86 was already removed — modern x86_64 emulators run arm64 via translation. -->
<RuntimeIdentifiers>android-arm64</RuntimeIdentifiers>
<AndroidPackageFormat>apk</AndroidPackageFormat>
<!-- CJK and Mideast encodings are needed for song metadata display.
Rare covers supplementary Unicode blocks. West is the default Latin set. -->
<MandroidI18n>CJK;Mideast;Rare;West;Other;</MandroidI18n>
<AndroidHttpClientHandlerType>Xamarin.Android.Net.AndroidMessageHandler</AndroidHttpClientHandlerType>
<!-- NullabilityInfoContextSupport is disabled by default for Android -->
<NullabilityInfoContextSupport>true</NullabilityInfoContextSupport>
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
<!-- Do NOT enable AndroidEnableMarshalMethods on .NET 10 with profiled AOT + trimming.
The build-time P/Invoke stub generator can produce stubs that crash in native code
when combined with partial AOT and trimmed assemblies — the crash bypasses managed
exception handling entirely, resulting in silent SIGSEGV/SIGABRT with no crash logs.
This is especially dangerous for apps with complex interop (UnmanagedCallersOnly,
unmanaged function pointers, reflection-based handle discovery).
The default runtime-generated trampolines are slower but proven reliable. -->
<AndroidEnableMarshalMethods>false</AndroidEnableMarshalMethods>
<NoWarn>$(NoWarn);NU1608;XA4301</NoWarn>
</PropertyGroup>
<!-- Release-only optimisations: AOT for low-latency gameplay, trimming for smaller APK.
Suppress trim analysis warnings because the project uses reflection extensively
(Newtonsoft.Json, Realm, AutoMapper, RuntimeBinder). -->
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<RunAOTCompilation>true</RunAOTCompilation>
<AndroidEnableProfiledAot>true</AndroidEnableProfiledAot>
<!-- Do NOT use EnableLLVM with profiled AOT on .NET 10.
The LLVM backend generates internally-inconsistent PLT (Procedure Linkage Table)
entries when only a subset of methods is AOT-compiled (profiled AOT). This causes
'plt_entry not met' assertions in aot-runtime.c at startup (SIGABRT on SDLThread).
The default Mono AOT compiler handles partial-image PLT generation correctly. -->
<SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode>
<!-- Keep IL bodies as a fallback for methods not covered by profiled AOT.
AndroidEnableProfiledAot only AOT-compiles methods in the startup profile; the remaining
methods require IL for JIT/interpretation. Stripping IL (AndroidStripILAfterAOT=true)
removes that fallback, causing 'plt_entry not met' assertions in aot-runtime.c when
the runtime encounters an un-AOT'd method (observed on .NET Timer thread at startup).
The ~20-30 MB size saving is not worth the crash risk. -->
<AndroidStripILAfterAOT>false</AndroidStripILAfterAOT>
<!-- Compress managed assemblies inside the APK (LZ4). Android extracts them on first run
but the download/APK size is significantly smaller. -->
<AndroidEnableAssemblyCompression>true</AndroidEnableAssemblyCompression>
<!-- Don't ship PDB files in the APK — they add ~15-20 MB.
Stack traces still work via embedded metadata. -->
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<!-- Force Microsoft.CSharp into the trimmer input graph (.NET 10+). -->
<!-- A bare TrimmerRootAssembly is ignored if the assembly is not in the -->
<!-- linker's input set; adding this reference ensures it is included. -->
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" NoWarn="NU1510" />
<TrimmerRootAssembly Include="Microsoft.CSharp" RootMode="all" />
<!-- Preserve ppy.Veldrid.SPIRV from trimming. The trimmer does not trace the
CrossCompileTarget enum usage in osu.Framework's VeldridShader/GLShader correctly
(the reference crosses assembly boundaries via a ProjectReference chain), causing
TypeLoadException: 'Could not resolve type Veldrid.SPIRV.CrossCompileTarget' at
startup when the renderer tries to compile shaders. -->
<TrimmerRootAssembly Include="ppy.Veldrid.SPIRV" RootMode="all" />
</ItemGroup>
<ItemGroup>
<!-- Use winnerspiros/osu-framework fork (net10.0-android, optimized) via submodule instead of ppy NuGet package -->
<ProjectReference Include="$(MSBuildThisFileDirectory)submodules/osu-framework/osu.Framework.Android/osu.Framework.Android.csproj" />
<!-- Suppress native assets from the desktop NativeLibs NuGet package.
ppy.osu.Framework.NativeLibs (transitive via osu.Framework.csproj) ships
runtimes/linux-arm64/native/libbass.so and friends built for GNU/Linux (they link
libc.so.6, libpthread.so.0, etc.). The .NET RID fallback chain for android-arm64
(android-arm64 → android → unix → any) causes the Linux ARM64 .so files to leak
into the APK even though the NuGet has an android/native/_._ placeholder.
The result: the APK ends up with a Linux libbass.so that cannot load on Android
(DllNotFoundException at startup).
ExcludeAssets="native" prevents NuGet from contributing any .so files;
the correct Android-built libraries are supplied by AndroidNativeLibrary below. -->
<PackageReference Include="ppy.osu.Framework.NativeLibs" Version="2025.806.0-nativelibs" ExcludeAssets="native" PrivateAssets="all" />
</ItemGroup>
<!-- Include framework native libraries (BASS audio, FFmpeg, etc.) from the submodule.
When using a NuGet package these are bundled automatically; with a ProjectReference
they must be declared explicitly or the app crashes at startup with
System.DllNotFoundException: bass (or similar).
Use forward slashes — backslash globs silently match zero files on Linux CI runners,
which produces an APK without libbass.so (and the other native libs). -->
<ItemGroup>
<AndroidNativeLibrary Include="$(MSBuildThisFileDirectory)submodules/osu-framework/osu.Framework.Android/arm64-v8a/*.so" Abi="arm64-v8a" />
</ItemGroup>
<!-- Fail the build early if critical native libraries are missing.
A missing .so means the app will crash on startup with DllNotFoundException.
This catches silent glob failures (e.g. uninitialised submodule, wrong path)
and NuGet restore failures for Veldrid.SPIRV. -->
<Target Name="ValidateFrameworkNativeLibraries" BeforeTargets="Build">
<Error Condition="!Exists('$(MSBuildThisFileDirectory)submodules/osu-framework/osu.Framework.Android/arm64-v8a/libbass.so')"
Text="libbass.so not found in submodules/osu-framework/osu.Framework.Android/arm64-v8a/. Ensure the osu-framework submodule is initialised: git submodule update --init --recursive" />
</Target>
<PropertyGroup>
<!-- Fody does not handle Android build well, and warns when unchanged.
Since Realm objects are not declared directly in Android projects, simply disable Fody. -->
<DisableFody>true</DisableFody>
</PropertyGroup>
<!-- Fix for .NET 10 Android AOT misclassifying native .so assets in runtime pack.
Only .so files need the AssetType override — the previous broader filter
(all non-DLL, non-PDB) incorrectly reclassified signing metadata and config
files, which corrupted the APK signature (INSTALL_PARSE_FAILED_NO_CERTIFICATES).
Scoped to Release only to avoid interfering with Debug builds. -->
<Target Name="FixRuntimePackAssetTypes" AfterTargets="ResolveRuntimePackAssets;ComputeFilesToPublish;ComputeResolvedFilesToPublishList"
Condition="'$(Configuration)' == 'Release'">
<ItemGroup>
<RuntimePackAsset Update="@(RuntimePackAsset)" Condition="'%(Extension)' == '.so'">
<AssetType>native</AssetType>
</RuntimePackAsset>
<ResolvedFileToPublish Update="@(ResolvedFileToPublish)" Condition="'%(Extension)' == '.so'">
<AssetType>native</AssetType>
</ResolvedFileToPublish>
</ItemGroup>
</Target>
</Project>