diff --git a/src/Microsoft.Android.Sdk.ILLink/PreserveLists/System.Private.CoreLib.xml b/src/Microsoft.Android.Sdk.ILLink/PreserveLists/System.Private.CoreLib.xml
new file mode 100644
index 00000000000..c5aea679db6
--- /dev/null
+++ b/src/Microsoft.Android.Sdk.ILLink/PreserveLists/System.Private.CoreLib.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddRidMetadataAttributeStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddRidMetadataAttributeStep.cs
new file mode 100644
index 00000000000..6ee4fe3d2e7
--- /dev/null
+++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddRidMetadataAttributeStep.cs
@@ -0,0 +1,100 @@
+using System;
+
+using Mono.Cecil;
+using Mono.Linker;
+using Mono.Linker.Steps;
+
+#if ILLINK
+using Microsoft.Android.Sdk.ILLink;
+#endif
+
+namespace MonoDroid.Tuner;
+
+public class AddRidMetadataAttributeStep : BaseStep
+{
+ protected override void ProcessAssembly (AssemblyDefinition assembly)
+ {
+ if (!Annotations.HasAction (assembly)) {
+ return;
+ }
+
+ var action = Annotations.GetAction (assembly);
+ if (action == AssemblyAction.Skip || action == AssemblyAction.Delete) {
+ return;
+ }
+
+ string? rid = null;
+#if ILLINK
+ if (!Context.TryGetCustomData ("XARuntimeIdentifier", out rid)) {
+ throw new InvalidOperationException ("Missing XARuntimeIdentifier custom data");
+ }
+#endif
+ if (String.IsNullOrEmpty (rid)) {
+ throw new InvalidOperationException ("RID must have a non-empty value");
+ }
+
+ AssemblyDefinition corlib = GetCorlib ();
+ MethodDefinition assemblyMetadataAttributeCtor = FindAssemblyMetadataAttributeCtor (corlib);
+ TypeDefinition systemString = GetSystemString (corlib);
+
+ var attr = new CustomAttribute (assembly.MainModule.ImportReference (assemblyMetadataAttributeCtor));
+ attr.ConstructorArguments.Add (new CustomAttributeArgument (systemString, "XamarinAndroidAbi")); // key
+
+ // TODO: figure out how to get the RID...
+ attr.ConstructorArguments.Add (new CustomAttributeArgument (systemString, rid)); // value
+
+ assembly.CustomAttributes.Add (attr);
+
+ if (action == AssemblyAction.Copy) {
+ Annotations.SetAction (assembly, AssemblyAction.Save);
+ }
+ }
+
+ TypeDefinition GetSystemString (AssemblyDefinition asm) => FindType (asm, "System.String", required: true);
+
+ AssemblyDefinition GetCorlib ()
+ {
+ const string ImportAssembly = "System.Private.CoreLib";
+ AssemblyDefinition? asm = Context.Resolve (AssemblyNameReference.Parse (ImportAssembly));
+ if (asm == null) {
+ throw new InvalidOperationException ($"Unable to import assembly '{ImportAssembly}'");
+ }
+
+ return asm;
+ }
+
+ MethodDefinition FindAssemblyMetadataAttributeCtor (AssemblyDefinition asm)
+ {
+ const string AttributeType = "System.Reflection.AssemblyMetadataAttribute";
+
+ TypeDefinition assemblyMetadataAttribute = FindType (asm, AttributeType, required: true);
+ foreach (MethodDefinition md in assemblyMetadataAttribute!.Methods) {
+ if (!md.IsConstructor) {
+ continue;
+ }
+
+ return md;
+ }
+
+ throw new InvalidOperationException ($"Unable to find the {AttributeType} type constructor");
+ }
+
+ TypeDefinition? FindType (AssemblyDefinition asm, string typeName, bool required)
+ {
+ foreach (ModuleDefinition md in asm.Modules) {
+ foreach (TypeDefinition et in md.Types) {
+ if (String.Compare (typeName, et.FullName, StringComparison.Ordinal) != 0) {
+ continue;
+ }
+
+ return et;
+ }
+ }
+
+ if (required) {
+ throw new InvalidOperationException ($"Internal error: required type '{typeName}' in assembly {asm} not found");
+ }
+
+ return null;
+ }
+}
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets
index 7400de192ff..0461633d57b 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.ILLink.targets
@@ -40,6 +40,7 @@ This file contains the .NET 5-specific targets to customize ILLink
https://github.com/dotnet/sdk/blob/a5393731b5b7b225692fff121f747fbbc9e8b140/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.ILLink.targets#L147
-->
<_TrimmerCustomData Include="XATargetFrameworkDirectories" Value="$(_XATargetFrameworkDirectories)" />
+ <_TrimmerCustomData Include="XARuntimeIdentifier" Value="$(RuntimeIdentifier)" Condition=" '$(_AndroidAddRuntimeIdentifierToAssemblies)' == 'true' " />
<_TrimmerCustomData
Condition=" '$(_ProguardProjectConfiguration)' != '' "
Include="ProguardConfiguration"
@@ -94,6 +95,12 @@ This file contains the .NET 5-specific targets to customize ILLink
BeforeStep="MarkStep"
Type="MonoDroid.Tuner.FixLegacyResourceDesignerStep"
/>
+ <_TrimmerCustomSteps
+ Condition=" '$(_AndroidAddRuntimeIdentifierToAssemblies)' == 'true' "
+ Include="$(_AndroidLinkerCustomStepAssembly)"
+ AfterStep="CleanStep"
+ Type="MonoDroid.Tuner.AddRidMetadataAttributeStep"
+ />
<_PreserveLists Include="$(MSBuildThisFileDirectory)..\PreserveLists\*.xml" />