diff --git a/src/Microsoft.Android.Sdk.ILLink/StripEmbeddedLibraries.cs b/src/Microsoft.Android.Sdk.ILLink/StripEmbeddedLibraries.cs
deleted file mode 100644
index 041bead3f92..00000000000
--- a/src/Microsoft.Android.Sdk.ILLink/StripEmbeddedLibraries.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-using Mono.Cecil;
-using Mono.Linker;
-using Mono.Linker.Steps;
-using System;
-using System.Linq;
-using Xamarin.Android.Tasks;
-
-namespace MonoDroid.Tuner
-{
- public class StripEmbeddedLibraries : 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;
-
- if (MonoAndroidHelper.IsFrameworkAssembly (assembly))
- return;
- bool assembly_modified = false;
- foreach (var mod in assembly.Modules) {
- foreach (var r in mod.Resources.ToArray ()) {
- if (ShouldStripResource (r)) {
- Context.LogMessage ($" Stripped {r.Name} from {assembly.Name.Name}.dll");
- mod.Resources.Remove (r);
- assembly_modified = true;
- }
- }
- }
- if (assembly_modified && action == AssemblyAction.Copy) {
- Annotations.SetAction (assembly, AssemblyAction.Save);
- }
- }
-
- bool ShouldStripResource (Resource r)
- {
- if (!(r is EmbeddedResource))
- return false;
- // embedded jars
- if (r.Name.EndsWith (".jar", StringComparison.InvariantCultureIgnoreCase))
- return true;
- // embedded AndroidNativeLibrary archive
- if (r.Name == "__AndroidNativeLibraries__.zip")
- return true;
- // embedded AndroidResourceLibrary archive
- if (r.Name == "__AndroidLibraryProjects__.zip")
- return true;
- // embedded AndroidEnvironment item
- if (r.Name.StartsWith ("__AndroidEnvironment__", StringComparison.Ordinal))
- return true;
- return false;
- }
- }
-}
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.LlvmIr.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.LlvmIr.targets
index 68fd6b77705..4be55630c91 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.LlvmIr.targets
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.LlvmIr.targets
@@ -7,6 +7,7 @@
+
<_RemoveRegisterFlag>$(MonoAndroidIntermediateAssemblyDir)shrunk\shrunk.flag
@@ -203,7 +204,6 @@
Type="MonoDroid.Tuner.AddKeepAlivesStep"
/>
- <_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" AfterStep="CleanStep" Type="MonoDroid.Tuner.StripEmbeddedLibraries" />
<_TrimmerCustomSteps
Condition=" '$(AndroidLinkResources)' == 'true' "
Include="$(_AndroidLinkerCustomStepAssembly)"
@@ -250,6 +250,22 @@
+
+
+
+ <_StripEmbeddedLibrariesAssembly Include="@(ResolvedFileToPublish)" Condition=" '%(Extension)' == '.dll' " />
+
+
+
+
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/StripEmbeddedLibraries.cs b/src/Xamarin.Android.Build.Tasks/Tasks/StripEmbeddedLibraries.cs
new file mode 100644
index 00000000000..7a65c4a8145
--- /dev/null
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/StripEmbeddedLibraries.cs
@@ -0,0 +1,116 @@
+#nullable enable
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Microsoft.Android.Build.Tasks;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using Mono.Cecil;
+
+namespace Xamarin.Android.Tasks;
+
+///
+/// An MSBuild task that strips embedded Android resources (.jar, __AndroidNativeLibraries__.zip,
+/// __AndroidLibraryProjects__.zip, __AndroidEnvironment__) from trimmed assemblies.
+///
+/// This runs in the inner build after ILLink but before ReadyToRun/crossgen2 compilation,
+/// so that R2R images are generated from the already-stripped assemblies.
+///
+public class StripEmbeddedLibraries : AndroidTask
+{
+ public override string TaskPrefix => "SEL";
+
+ [Required]
+ public ITaskItem [] Assemblies { get; set; } = [];
+
+ public bool Deterministic { get; set; }
+
+ public override bool RunTask ()
+ {
+ var resolver = new DefaultAssemblyResolver ();
+ var searchDirectories = new HashSet (StringComparer.OrdinalIgnoreCase);
+
+ foreach (var assembly in Assemblies) {
+ var dir = Path.GetFullPath (Path.GetDirectoryName (assembly.ItemSpec) ?? "");
+ if (searchDirectories.Add (dir)) {
+ resolver.AddSearchDirectory (dir);
+ }
+ }
+
+ try {
+ foreach (var assembly in Assemblies) {
+ if (MonoAndroidHelper.IsFrameworkAssembly (assembly)) {
+ continue;
+ }
+
+ StripAssembly (assembly.ItemSpec, resolver);
+ }
+ } finally {
+ resolver.Dispose ();
+ }
+
+ return !Log.HasLoggedErrors;
+ }
+
+ void StripAssembly (string assemblyPath, IAssemblyResolver resolver)
+ {
+ string pdbPath = Path.ChangeExtension (assemblyPath, ".pdb");
+ bool havePdb = File.Exists (pdbPath);
+
+ var readerParams = new ReaderParameters {
+ ReadSymbols = havePdb,
+ ReadWrite = true,
+ AssemblyResolver = resolver,
+ };
+
+ bool assembly_modified = false;
+
+ using (var assembly = AssemblyDefinition.ReadAssembly (assemblyPath, readerParams)) {
+ foreach (var module in assembly.Modules) {
+ foreach (var resource in module.Resources.ToArray ()) {
+ if (ShouldStripResource (resource)) {
+ Log.LogDebugMessage ($" Stripped {resource.Name} from {assembly.Name.Name}.dll");
+ module.Resources.Remove (resource);
+ assembly_modified = true;
+ }
+ }
+ }
+
+ if (!assembly_modified) {
+ return;
+ }
+
+ Log.LogDebugMessage ($" Writing stripped assembly: {assemblyPath}");
+ assembly.Write (new WriterParameters {
+ WriteSymbols = havePdb,
+ DeterministicMvid = Deterministic,
+ });
+ }
+ }
+
+ ///
+ /// Determines whether a resource should be stripped from the assembly.
+ /// Matches the same criteria as the old ILLink StripEmbeddedLibraries step.
+ ///
+ internal static bool ShouldStripResource (Resource resource)
+ {
+ if (!(resource is EmbeddedResource))
+ return false;
+ // Embedded jars
+ if (resource.Name.EndsWith (".jar", StringComparison.InvariantCultureIgnoreCase))
+ return true;
+ // Embedded AndroidNativeLibrary archive
+ if (resource.Name == "__AndroidNativeLibraries__.zip")
+ return true;
+ // Embedded AndroidResourceLibrary archive
+ if (resource.Name == "__AndroidLibraryProjects__.zip")
+ return true;
+ // Embedded AndroidEnvironment items
+ if (resource.Name.StartsWith ("__AndroidEnvironment__", StringComparison.Ordinal))
+ return true;
+ return false;
+ }
+
+}