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
143 lines (134 loc) · 9.52 KB
/
Copy pathosu.Android.props
File metadata and controls
143 lines (134 loc) · 9.52 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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<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>
<!-- Suppress XA0141 page-size warnings. ELF patching is disabled for all configurations
(see PatchElfPageSizeEnabled below) to prevent APK signature corruption.
The XA0141 warning is therefore expected and harmless.
AndroidPageSize16KBCompatibilityCheck=false should suppress the check, but Android SDK
36.1.53 still emits XA0141 in some build orderings, so we also add it to NoWarn. -->
<AndroidPageSize16KBCompatibilityCheck>false</AndroidPageSize16KBCompatibilityCheck>
<NoWarn>$(NoWarn);XA0141;NU1608;XA4301</NoWarn>
<!-- Disable ELF alignment patching for ALL configurations.
The custom PatchElfPageSize task can run concurrently with the Android packaging step
because MSBuild's BeforeTargets="Build" fires for every ABI sub-build, which often
overlaps with the main APK assembly pass. Patching .so files in the NuGet cache while
they are being read and packed into the APK can corrupt the ZIP/signing structures,
producing an APK with a null certificate array (INSTALL_PARSE_FAILED_NO_CERTIFICATES).
TODO: Re-enable once ppy.Veldrid.SPIRV ships 16 KB-aligned native libraries so no
patching is needed at all, or once the build targets are re-sequenced so
patching always completes before packaging starts. -->
<PatchElfPageSizeEnabled>false</PatchElfPageSizeEnabled>
</PropertyGroup>
<!-- Patch NuGet-provided .so files that ship with 4 KB ELF alignment to 16 KB.
See build/PatchElfPageSize.targets for details.
TODO: Remove once ppy.Veldrid.SPIRV ships 16 KB-aligned native libraries. -->
<Import Project="$(MSBuildThisFileDirectory)build\PatchElfPageSize.targets" />
<!-- 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" />
</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 libbass.so is missing.
A missing libbass.so means the app will crash on startup with DllNotFoundException.
This catches silent glob failures (e.g. uninitialised submodule, wrong path). -->
<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>