Skip to content

Commit 89edafc

Browse files
[illink] Remove custom types marking for types which XA does not own for netcore (#5354)
This is or will be handled by BCL libraries and XA tooling should try not to interfere with more fine tuned handling done by BCL. Simplifies `[Preserve]` attribute implementation and removes old code to preserve serialization, which doesn't work well with new .NET5/6 runtime libraries. (the old serialization code: https://github.com/xamarin/xamarin-android/blob/master/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/ApplyPreserveAttribute.cs#L57-L82) The serialization is currently [broken](dotnet/runtime#45559) and will be fixed in runtime libs. Part of `CustomLinkDescriptionPreserve` test is thus disabled. Also the attribute removal is now handled in illink. The serialization fix leads to great reduction of assemblies size in simple XA test app by cca 1MB, apkdiff before/after: Summary: - 1,199,411 Assemblies -55.66% (of 2,154,984) - 1,206,333 Package size difference -13.37% (of 9,024,291) Co-authored-by: Radek Doulik <[email protected]>
1 parent 97190b6 commit 89edafc

File tree

9 files changed

+39
-59
lines changed

9 files changed

+39
-59
lines changed

src/Microsoft.Android.Sdk.ILLink/ApplyPreserveAttributeBase.cs renamed to src/Microsoft.Android.Sdk.ILLink/ApplyPreserveAttribute.cs

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@
1111
namespace Microsoft.Android.Sdk.ILLink
1212
{
1313

14-
public abstract class ApplyPreserveAttributeBase : BaseSubStep {
15-
16-
// set 'removeAttribute' to true if you want the preserved attribute to be removed from the final assembly
17-
protected abstract bool IsPreservedAttribute (ICustomAttributeProvider provider, CustomAttribute attribute, out bool removeAttribute);
14+
public class ApplyPreserveAttribute : BaseSubStep {
1815

1916
public override SubStepTargets Targets {
2017
get {
@@ -66,7 +63,7 @@ public override void ProcessEvent (EventDefinition @event)
6663

6764
void MarkMethodIfPreserved (MethodDefinition method)
6865
{
69-
foreach (var attribute in GetPreserveAttributes (method))
66+
foreach (var attribute in GetPreserveAttributes (method))
7067
MarkMethod (method, attribute);
7168
}
7269

@@ -126,6 +123,9 @@ void PreserveUnconditional (IMetadataTokenProvider provider)
126123

127124
void TryApplyPreserveAttribute (TypeDefinition type)
128125
{
126+
if (!type.HasCustomAttributes)
127+
return;
128+
129129
foreach (var attribute in GetPreserveAttributes (type)) {
130130
Annotations.Mark (type);
131131

@@ -138,28 +138,9 @@ void TryApplyPreserveAttribute (TypeDefinition type)
138138
}
139139
}
140140

141-
List<CustomAttribute> GetPreserveAttributes (ICustomAttributeProvider provider)
141+
static IEnumerable<CustomAttribute> GetPreserveAttributes (ICustomAttributeProvider provider)
142142
{
143-
List<CustomAttribute> attrs = new List<CustomAttribute> ();
144-
145-
if (!provider.HasCustomAttributes)
146-
return attrs;
147-
148-
var attributes = provider.CustomAttributes;
149-
150-
for (int i = attributes.Count - 1; i >= 0; i--) {
151-
var attribute = attributes [i];
152-
153-
bool remote_attribute;
154-
if (!IsPreservedAttribute (provider, attribute, out remote_attribute))
155-
continue;
156-
157-
attrs.Add (attribute);
158-
if (remote_attribute)
159-
attributes.RemoveAt (i);
160-
}
161-
162-
return attrs;
143+
return provider.CustomAttributes.Where (a => a.Constructor.DeclaringType.Name == "PreserveAttribute");
163144
}
164145
}
165146
}

src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<Compile Remove="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\LinkerOptions.cs" />
2929

3030
<!--Steps that are upstreamed, these are OK to remove-->
31+
<Compile Remove="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\ApplyPreserveAttribute.cs" />
3132
<Compile Remove="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\OutputStepWithTimestamps.cs" />
3233
<Compile Remove="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\PreserveCode.cs" />
3334
<Compile Remove="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\PreserveDynamicTypes.cs" />
@@ -36,6 +37,7 @@
3637
<Compile Remove="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\PreserveRuntimeSerialization.cs" />
3738
<Compile Remove="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\PreserveTlsProvider.cs" />
3839
<Compile Remove="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\PreserveTypeConverters.cs" />
40+
<Compile Remove="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\RemoveAttributes.cs" />
3941

4042
<!--TODO: Subclasses MarkStep-->
4143
<Compile Remove="..\Xamarin.Android.Build.Tasks\Linker\MonoDroid.Tuner\MonoDroidMarkStep.cs" />

src/Microsoft.Android.Sdk.ILLink/SetupStep.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ protected override void Process ()
4343
subSteps2.Add (new PreserveApplications ());
4444
subSteps2.Add (new PreserveRegistrations (cache));
4545
subSteps2.Add (new PreserveJavaInterfaces ());
46-
subSteps2.Add (new RemoveAttributes ());
4746

4847
InsertAfter (new FixAbstractMethodsStep (cache), "RemoveUnreachableBlocksStep");
4948
InsertAfter (subSteps2, "RemoveUnreachableBlocksStep");
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<linker>
2+
<assembly fullname="Mono.Android">
3+
<type fullname="Android.Runtime.PreserveAttribute">
4+
<attribute internal="RemoveAttributeInstances" />
5+
</type>
6+
<type fullname="Android.Runtime.IntDefinitionAttribute">
7+
<attribute internal="RemoveAttributeInstances" />
8+
</type>
9+
</assembly>
10+
</linker>

src/Mono.Android/Mono.Android.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@
8585

8686
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
8787
<ProjectReference Include="..\..\external\Java.Interop\src\Java.Interop\Java.Interop.csproj" />
88+
89+
<EmbeddedResource Include="ILLink/ILLink.LinkAttributes.xml" />
8890
</ItemGroup>
8991

9092
<ItemGroup>

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -85,38 +85,14 @@ public void CheckIncludedAssemblies ()
8585
var expectedFiles = Builder.UseDotNet ?
8686
new [] {
8787
"Java.Interop.dll",
88-
"Microsoft.Win32.Primitives.dll",
8988
"Mono.Android.dll",
90-
"System.Collections.NonGeneric.dll",
9189
"System.ComponentModel.Primitives.dll",
9290
"System.Console.dll",
93-
"System.Formats.Asn1.dll",
94-
"System.IO.Compression.Brotli.dll",
95-
"System.IO.Compression.dll",
96-
"System.IO.FileSystem.dll",
9791
"System.Linq.Expressions.dll",
98-
"System.Net.Http.dll",
99-
"System.Net.NameResolution.dll",
100-
"System.Net.NetworkInformation.dll",
10192
"System.Net.Primitives.dll",
102-
"System.Net.Quic.dll",
103-
"System.Net.Security.dll",
104-
"System.Net.Sockets.dll",
10593
"System.ObjectModel.dll",
106-
"System.Private.Uri.dll",
107-
"System.Private.Xml.dll",
108-
"System.Private.Xml.Linq.dll",
109-
"System.Runtime.CompilerServices.Unsafe.dll",
110-
"System.Runtime.InteropServices.RuntimeInformation.dll",
111-
"System.Runtime.Numerics.dll",
112-
"System.Security.Cryptography.Encoding.dll",
113-
"System.Security.Cryptography.OpenSsl.dll",
114-
"System.Security.Cryptography.X509Certificates.dll",
11594
"System.Runtime.Serialization.Primitives.dll",
116-
"System.Security.Cryptography.Algorithms.dll",
11795
"System.Security.Cryptography.Primitives.dll",
118-
"System.Text.RegularExpressions.dll",
119-
"System.Threading.Channels.dll",
12096
"System.Private.CoreLib.dll",
12197
"System.Collections.Concurrent.dll",
12298
"System.Collections.dll",

tests/MSBuildDeviceIntegration/Resources/LinkDescTest/MainActivityReplacement.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,9 @@ protected override void OnCreate(Bundle bundle)
117117
Android.Util.Log.Info(TAG, LinkTestLib.Bug21578.MulticastOption_ShouldNotBeStripped());
118118
Android.Util.Log.Info(TAG, LinkTestLib.Bug21578.MulticastOption_ShouldNotBeStripped2());
119119
Android.Util.Log.Info(TAG, LinkTestLib.Bug35195.AttemptCreateTable());
120+
#if !NET
120121
Android.Util.Log.Info(TAG, LinkTestLib.Bug36250.SerializeSearchRequestWithDictionary());
121-
122+
#endif
122123
Android.Util.Log.Info(TAG, "All regression tests completed.");
123124
}
124125
}

tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -330,12 +330,6 @@ public class LinkModeFullClass {
330330
return sr.ReadToEnd ();
331331
},
332332
},
333-
new BuildItem.Source ("Bug36250.cs") {
334-
TextContent = () => {
335-
using (var sr = new StreamReader (typeof (InstallAndRunTests).Assembly.GetManifestResourceStream ("Xamarin.Android.Build.Tests.Resources.LinkDescTest.Bug36250.cs")))
336-
return sr.ReadToEnd ();
337-
},
338-
},
339333
new BuildItem.Source ("Bug35195.cs") {
340334
TextContent = () => {
341335
using (var sr = new StreamReader (typeof (InstallAndRunTests).Assembly.GetManifestResourceStream ("Xamarin.Android.Build.Tests.Resources.LinkDescTest.Bug35195.cs")))
@@ -345,6 +339,17 @@ public class LinkModeFullClass {
345339
},
346340
};
347341

342+
if (!Builder.UseDotNet) {
343+
// DataContractSerializer is not trimming safe
344+
// https://github.com/dotnet/runtime/issues/45559
345+
lib2.Sources.Add (new BuildItem.Source ("Bug36250.cs") {
346+
TextContent = () => {
347+
using (var sr = new StreamReader (typeof (InstallAndRunTests).Assembly.GetManifestResourceStream ("Xamarin.Android.Build.Tests.Resources.LinkDescTest.Bug36250.cs")))
348+
return sr.ReadToEnd ();
349+
},
350+
});
351+
}
352+
348353
proj = new XamarinFormsAndroidApplicationProject () {
349354
IsRelease = true,
350355
AndroidLinkModeRelease = linkMode,

tests/MSBuildDeviceIntegration/Tests/InstallTests.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,11 @@ public void InstallWithoutSharedRuntime ()
217217
// "The Shared Runtime should not have been installed.");
218218
var directorylist = GetContentFromAllOverrideDirectories (proj.PackageName);
219219
StringAssert.Contains ($"{proj.ProjectName}.dll", directorylist, $"{proj.ProjectName}.dll should exist in the .__override__ directory.");
220-
StringAssert.Contains ($"System.dll", directorylist, $"System.dll should exist in the .__override__ directory.");
220+
if (Builder.UseDotNet)
221+
StringAssert.Contains ($"System.Private.CoreLib.dll", directorylist, $"System.Private.CoreLib.dll should exist in the .__override__ directory.");
222+
else
223+
StringAssert.Contains ($"System.dll", directorylist, $"System.dll should exist in the .__override__ directory.");
224+
221225
StringAssert.Contains ($"Mono.Android.dll", directorylist, $"Mono.Android.dll should exist in the .__override__ directory.");
222226
Assert.IsTrue (builder.Uninstall (proj), "unnstall should have succeeded.");
223227
}

0 commit comments

Comments
 (0)