-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[compatibility] IsTrimmable support, fix linker warnings #3161
Merged
Commits on Oct 28, 2021
-
[compatibility] IsTrimmable support, fix linker warnings
To make `Microsoft.Maui.Controls.Compatibility.dll` "trimmable", we can simply add: [assembly: AssemblyMetadata ("IsTrimmable", "True")] This doesn't mean it actually *works* though! We should enable linker warnings and fix what it finds. To view linker warnings in .NET 6, you can do: > .\bin\dotnet\dotnet.exe build ` .\src\Controls\samples\Controls.Sample.SingleProject\Maui.Controls.Sample.SingleProject.csproj -f net6.0-android ` -c Release ` -p:SuppressTrimAnalysisWarnings=false ` -p:TrimmerSingleWarn=false ` -bl Then open the `msbuild.binlog` file and filter the warnings (that get upgraded to errors) for `src/Compatibility`: src\Compatibility\Core\src\Android\Deserializer.cs(38,6): error IL2026: Microsoft.Maui.Controls.Compatibility.Platform.Android.Deserializer.<>c.<DeserializePropertiesAsync>b__2_0(): Using member 'System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved. src\Compatibility\Core\src\Android\Deserializer.cs(71,6): error IL2026: Microsoft.Maui.Controls.Compatibility.Platform.Android.Deserializer.<>c__DisplayClass3_0.<SerializePropertiesAsync>b__0(): Using member 'System.Runtime.Serialization.XmlObjectSerializer.WriteObject(XmlDictionaryWriter,Object)' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Data Contract Serialization and Deserialization might require types that cannot be statically analyzed. Make sure all of the required types are preserved. src\Compatibility\Core\src\Android\AndroidAppIndexProvider.cs(14,5): error IL2072: Microsoft.Maui.Controls.Compatibility.Platform.Android.AndroidAppIndexProvider.AndroidAppIndexProvider(Context): '#0' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' in call to 'System.Object System.Activator::CreateInstance(System.Type,System.Object[],System.Object[])'. The return value of method 'System.Type.GetType(String,Boolean)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. src\Compatibility\Core\src\AppHostBuilderExtensions.cs(49,4): error IL2091: Microsoft.Maui.Controls.Hosting.MauiAppBuilderExtensions.UseMauiApp<TApp>(MauiAppBuilder): 'TImplementation' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' in 'Microsoft.Extensions.DependencyInjection.Extensions.ServiceCollectionDescriptorExtensions.TryAddSingleton<TService,TImplementation>(IServiceCollection)'. The generic parameter 'TApp' of 'Microsoft.Maui.Controls.Hosting.MauiAppBuilderExtensions.UseMauiApp<TApp>(MauiAppBuilder)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. src\Compatibility\Core\src\Android\NativeBindingservice.cs(16,4): error IL2075: Microsoft.Maui.Controls.Compatibility.Platform.Android.NativeBindingService.TrySetBinding(Object,String,BindingBase): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicProperties' in call to 'System.Type.GetProperty(String)'. The return value of method 'System.Type System.Object::GetType()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. src\Compatibility\Core\src\Android\ResourceManager.cs(28,4): error IL2026: Microsoft.Maui.Controls.Compatibility.Platform.Android.ResourceManager.FindType(String,String): Using member 'System.Reflection.Assembly.GetTypes()' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Types might be removed. src\Compatibility\Core\src\Android\ResourceManager.cs(419,4): error IL2070: Microsoft.Maui.Controls.Compatibility.Platform.Android.ResourceManager.GetId(Type,String): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicFields' in call to 'System.Type.GetFields()'. The parameter 'type' of method 'Microsoft.Maui.Controls.Compatibility.Platform.Android.ResourceManager.GetId(Type,String)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. src\Compatibility\Core\src\Android\ResourceManager.cs(432,5): error IL2070: Microsoft.Maui.Controls.Compatibility.Platform.Android.ResourceManager.GetId(Type,String): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicProperties' in call to 'System.Type.GetProperties()'. The parameter 'type' of method 'Microsoft.Maui.Controls.Compatibility.Platform.Android.ResourceManager.GetId(Type,String)' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. I went through applying the new linker attributes to resolve these issues in this assembly. In most cases, I simply added C# attributes to solve warnings. However, a couple places needed code changes: * `Deserializer`, I removed usage of a lambda for a regular method. There isn't a way to decorate lambdas with C# attributes to appease the linker. * `ResourceManager.FindType()`, I replaced System.Linq usage with a `foreach` loop that the linker could better understand (lambdas again!). This should generally improve performance, anyway. Lastly, I had to actually add some attributes to `DependencyService`, otherwise we got crashes at startup like: android.runtime.JavaProxyThrowable: System.MissingMethodException: Arg_NoDefCTor, Microsoft.Maui.Controls.Compatibility.Platform.Android.NativeValueConverterService at System.RuntimeType.CreateInstanceMono(Boolean , Boolean ) at System.RuntimeType.CreateInstanceDefaultCtor(Boolean , Boolean ) at System.Activator.CreateInstance(Type , Boolean , Boolean ) at System.Activator.CreateInstance(Type , Boolean ) at System.Activator.CreateInstance(Type ) at Microsoft.Maui.Controls.DependencyService.Get[INativeValueConverterService](DependencyFetchTarget fetchTarget) at Microsoft.Maui.Controls.Xaml.TypeConversionExtensions.ConvertTo(Object value, Type toType, Func`1 getConverter, IServiceProvider serviceProvider, Exception& exception) at Microsoft.Maui.Controls.Xaml.TypeConversionExtensions.ConvertTo(Object value, Type toType, Func`1 minfoRetriever, IServiceProvider serviceProvider, Exception& exception) at Microsoft.Maui.Controls.Xaml.ValueConverterProvider.Convert(Object value, Type toType, Func`1 minfoRetriever, IServiceProvider serviceProvider) at Microsoft.Maui.Controls.Xaml.AppThemeBindingExtension.Microsoft.Maui.Controls.Xaml.IMarkupExtension<Microsoft.Maui.Controls.BindingBase>.ProvideValue(IServiceProvider serviceProvider) at Maui.Controls.Sample.XamlApp.InitializeComponent() ~~ Results ~~ I built `Maui.Controls.Sample.SingleProject.csproj` with `-p:AndroidUseAssemblyStore=false`, so we can see the size differences of individual assemblies. * Before 30275786 bytes * After 30181399 bytes > apkdiff -f before.apk after.apk Size difference in bytes ([*1] apk1 only, [*2] apk2 only): + 437 assemblies/Microsoft.Maui.Controls.dll + 161 assemblies/x86/System.Private.CoreLib.dll + 160 assemblies/arm64-v8a/System.Private.CoreLib.dll + 139 assemblies/armeabi-v7a/System.Private.CoreLib.dll + 127 assemblies/x86_64/System.Private.CoreLib.dll + 28 assemblies/System.Runtime.dll + 1 assemblies/Maui.Controls.Sample.SingleProject.dll - 1 assemblies/Microsoft.Maui.Controls.Xaml.dll - 15 assemblies/System.Xml.ReaderWriter.dll - 16 assemblies/System.Threading.dll - 231 META-INF/BNDLTOOL.SF - 231 META-INF/MANIFEST.MF - 2,498 assemblies/System.Runtime.Serialization.Xml.dll *1 - 3,523 assemblies/System.IO.IsolatedStorage.dll *1 - 6,341 assemblies/Mono.Android.dll - 8,352 lib/armeabi-v7a/libxamarin-app.so - 8,352 lib/x86/libxamarin-app.so - 8,408 lib/arm64-v8a/libxamarin-app.so - 8,408 lib/x86_64/libxamarin-app.so - 38,104 classes.dex - 72,810 assemblies/Microsoft.Maui.Controls.Compatibility.dll Summary: - 462 Other entries -0.00% (of 12,105,588) - 84,151 Assemblies -0.82% (of 10,293,792) - 38,104 Dalvik executables -0.59% (of 6,486,156) - 33,520 Shared libraries -0.18% (of 18,486,516) - 183,296 Uncompressed assemblies -0.81% (of 22,604,792) - 94,387 Package size difference -0.31% (of 30,275,786) An average of 10 runs on a Pixel 5, seems to show a difference in startup as well: Before: Activity: Displayed 1.676s After: Activity: Displayed 1.642s I think this might help startup by ~34ms?
Configuration menu - View commit details
-
Copy full SHA for 8ee080f - Browse repository at this point
Copy the full SHA 8ee080fView commit details
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.