diff --git a/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj b/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj
index 3757ed34b68..92c92c0ee94 100644
--- a/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj
+++ b/src/Microsoft.Android.Sdk.ILLink/Microsoft.Android.Sdk.ILLink.csproj
@@ -14,7 +14,6 @@
-
diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesHelper.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesHelper.cs
new file mode 100644
index 00000000000..5eb15079c14
--- /dev/null
+++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesHelper.cs
@@ -0,0 +1,125 @@
+using System;
+using System.Linq;
+using Java.Interop.Tools.Cecil;
+using Mono.Cecil;
+using Mono.Cecil.Cil;
+using Xamarin.Android.Tasks;
+
+namespace MonoDroid.Tuner
+{
+ static class AddKeepAlivesHelper
+ {
+ internal static bool AddKeepAlives (AssemblyDefinition assembly, IMetadataResolver resolver, Func getCorlibAssembly, Action logMessage)
+ {
+ if (!assembly.MainModule.HasTypeReference ("Java.Lang.Object"))
+ return false;
+
+ // Anything that was built against .NET for Android will have
+ // keep-alives already compiled in.
+ if (MonoAndroidHelper.IsDotNetAndroidAssembly (assembly))
+ return false;
+
+ MethodDefinition? methodKeepAlive = null;
+ bool changed = false;
+ foreach (TypeDefinition type in assembly.MainModule.Types)
+ changed |= ProcessType (type, resolver, ref methodKeepAlive, getCorlibAssembly, logMessage);
+
+ return changed;
+ }
+
+ static bool ProcessType (TypeDefinition type, IMetadataResolver resolver, ref MethodDefinition? methodKeepAlive, Func getCorlibAssembly, Action logMessage)
+ {
+ bool changed = false;
+ if (MightNeedFix (type, resolver))
+ changed |= AddKeepAlives (type, ref methodKeepAlive, getCorlibAssembly, logMessage);
+
+ if (type.HasNestedTypes) {
+ foreach (var t in type.NestedTypes) {
+ changed |= ProcessType (t, resolver, ref methodKeepAlive, getCorlibAssembly, logMessage);
+ }
+ }
+
+ return changed;
+ }
+
+ static bool MightNeedFix (TypeDefinition type, IMetadataResolver resolver)
+ {
+ return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", resolver);
+ }
+
+ static bool AddKeepAlives (TypeDefinition type, ref MethodDefinition? methodKeepAlive, Func getCorlibAssembly, Action logMessage)
+ {
+ bool changed = false;
+ foreach (MethodDefinition method in type.Methods) {
+ if (method.Parameters.Count == 0)
+ continue;
+
+ if (!method.CustomAttributes.Any (a => a.AttributeType.FullName == "Android.Runtime.RegisterAttribute"))
+ continue;
+
+ var instructions = method.Body.Instructions;
+
+ var found = false;
+ for (int off = Math.Max (0, instructions.Count - 6); off < instructions.Count; off++) {
+ var current = instructions [off];
+ if (current.OpCode == OpCodes.Call && current.Operand.ToString ().Contains ("System.GC::KeepAlive")) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+
+ var processor = method.Body.GetILProcessor ();
+ var module = method.DeclaringType.Module;
+ var end = instructions.Last ();
+ if (end.Previous.OpCode == OpCodes.Endfinally)
+ end = end.Previous;
+
+ for (int i = 0; i < method.Parameters.Count; i++) {
+ if (method.Parameters [i].ParameterType.IsValueType || method.Parameters [i].ParameterType.FullName == "System.String")
+ continue;
+
+ if (methodKeepAlive == null)
+ methodKeepAlive = GetKeepAliveMethod (getCorlibAssembly, logMessage);
+
+ if (methodKeepAlive == null) {
+ logMessage ("Unable to add KeepAlive call, did not find System.GC.KeepAlive method.");
+ break;
+ }
+
+ processor.InsertBefore (end, GetLoadArgumentInstruction (method.IsStatic ? i : i + 1, method.Parameters [i]));
+ processor.InsertBefore (end, Instruction.Create (OpCodes.Call, module.ImportReference (methodKeepAlive)));
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ static MethodDefinition? GetKeepAliveMethod (Func getCorlibAssembly, Action logMessage)
+ {
+ var corlibAssembly = getCorlibAssembly ();
+ if (corlibAssembly == null)
+ return null;
+
+ var gcType = Extensions.GetType (corlibAssembly, "System.GC");
+ if (gcType == null)
+ return null;
+
+ return Extensions.GetMethod (gcType, "KeepAlive", new string [] { "System.Object" });
+ }
+
+ // Adapted from src/Mono.Android.Export/Mono.CodeGeneration/CodeArgumentReference.cs
+ static Instruction GetLoadArgumentInstruction (int argNum, ParameterDefinition parameter)
+ {
+ switch (argNum) {
+ case 0: return Instruction.Create (OpCodes.Ldarg_0);
+ case 1: return Instruction.Create (OpCodes.Ldarg_1);
+ case 2: return Instruction.Create (OpCodes.Ldarg_2);
+ case 3: return Instruction.Create (OpCodes.Ldarg_3);
+ default: return Instruction.Create (OpCodes.Ldarg, parameter);
+ }
+ }
+ }
+}
diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs
index 0ca2fa7f597..32f69e5e70f 100644
--- a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs
+++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/AddKeepAlivesStep.cs
@@ -1,169 +1,23 @@
-using System;
-using System.Linq;
-using Java.Interop.Tools.Cecil;
using Mono.Cecil;
-using Mono.Cecil.Cil;
-using Mono.Linker;
using Mono.Linker.Steps;
using Xamarin.Android.Tasks;
namespace MonoDroid.Tuner
{
- public class AddKeepAlivesStep : BaseStep
-#if !ILLINK
- , IAssemblyModifierPipelineStep
-#endif // !ILLINK
+ public class AddKeepAlivesStep : BaseStep, IAssemblyModifierPipelineStep
{
- protected override void ProcessAssembly (AssemblyDefinition assembly)
- {
- var action = Annotations.HasAction (assembly) ? Annotations.GetAction (assembly) : AssemblyAction.Skip;
- if (action == AssemblyAction.Delete)
- return;
-
- if (AddKeepAlives (assembly)) {
- if (action == AssemblyAction.Skip || action == AssemblyAction.Copy)
- Annotations.SetAction (assembly, AssemblyAction.Save);
- }
- }
-
-#if !ILLINK
public void ProcessAssembly (AssemblyDefinition assembly, StepContext context)
{
// Only run this step on user Android assemblies
if (!context.IsAndroidUserAssembly)
return;
- context.IsAssemblyModified |= AddKeepAlives (assembly);
- }
-#endif // !ILLINK
-
- internal bool AddKeepAlives (AssemblyDefinition assembly)
- {
- if (!assembly.MainModule.HasTypeReference ("Java.Lang.Object"))
- return false;
-
- // Anything that was built against .NET for Android will have
- // keep-alives already compiled in.
- if (MonoAndroidHelper.IsDotNetAndroidAssembly (assembly))
- return false;
-
- bool changed = false;
- foreach (TypeDefinition type in assembly.MainModule.Types)
- changed |= ProcessType (type);
-
- return changed;
- }
-
- bool ProcessType (TypeDefinition type)
- {
- bool changed = false;
- if (MightNeedFix (type))
- changed |= AddKeepAlives (type);
-
- if (type.HasNestedTypes) {
- foreach (var t in type.NestedTypes) {
- changed |= ProcessType (t);
- }
- }
-
- return changed;
- }
-
- bool MightNeedFix (TypeDefinition type)
- {
- return !type.IsAbstract && type.IsSubclassOf ("Java.Lang.Object", Context);
- }
-
- MethodDefinition? methodKeepAlive = null;
-
- bool AddKeepAlives (TypeDefinition type)
- {
- bool changed = false;
- foreach (MethodDefinition method in type.Methods) {
- if (method.Parameters.Count == 0)
- continue;
-
- if (!method.CustomAttributes.Any (a => a.AttributeType.FullName == "Android.Runtime.RegisterAttribute"))
- continue;
-
- var instructions = method.Body.Instructions;
-
- var found = false;
- for (int off = Math.Max (0, instructions.Count - 6); off < instructions.Count; off++) {
- var current = instructions [off];
- if (current.OpCode == OpCodes.Call && current.Operand.ToString ().Contains ("System.GC::KeepAlive")) {
- found = true;
- break;
- }
- }
-
- if (found)
- continue;
-
- var processor = method.Body.GetILProcessor ();
- var module = method.DeclaringType.Module;
- var end = instructions.Last ();
- if (end.Previous.OpCode == OpCodes.Endfinally)
- end = end.Previous;
-
- for (int i = 0; i < method.Parameters.Count; i++) {
- if (method.Parameters [i].ParameterType.IsValueType || method.Parameters [i].ParameterType.FullName == "System.String")
- continue;
-
- if (methodKeepAlive == null)
- methodKeepAlive = GetKeepAliveMethod ();
-
- if (methodKeepAlive == null) {
- LogMessage ("Unable to add KeepAlive call, did not find System.GC.KeepAlive method.");
- break;
- }
-
- processor.InsertBefore (end, GetLoadArgumentInstruction (method.IsStatic ? i : i + 1, method.Parameters [i]));
- processor.InsertBefore (end, Instruction.Create (OpCodes.Call, module.ImportReference (methodKeepAlive)));
- changed = true;
- }
- }
- return changed;
- }
-
- protected virtual AssemblyDefinition GetCorlibAssembly ()
- {
- return Context.GetAssembly ("System.Private.CoreLib");
- }
-
- MethodDefinition? GetKeepAliveMethod ()
- {
- var corlibAssembly = GetCorlibAssembly ();
- if (corlibAssembly == null)
- return null;
-
- var gcType = Extensions.GetType (corlibAssembly, "System.GC");
- if (gcType == null)
- return null;
-
- return Extensions.GetMethod (gcType, "KeepAlive", new string [] { "System.Object" });
- }
-
- public
-#if !ILLINK
- override
-#endif
- void LogMessage (string message)
- {
- Context.LogMessage (message);
- }
-
- // Adapted from src/Mono.Android.Export/Mono.CodeGeneration/CodeArgumentReference.cs
- static Instruction GetLoadArgumentInstruction (int argNum, ParameterDefinition parameter)
- {
- switch (argNum) {
- case 0: return Instruction.Create (OpCodes.Ldarg_0);
- case 1: return Instruction.Create (OpCodes.Ldarg_1);
- case 2: return Instruction.Create (OpCodes.Ldarg_2);
- case 3: return Instruction.Create (OpCodes.Ldarg_3);
- default: return Instruction.Create (OpCodes.Ldarg, parameter);
- }
+ context.IsAssemblyModified |= AddKeepAlivesHelper.AddKeepAlives (
+ assembly,
+ Context,
+ () => Context.GetAssembly ("System.Private.CoreLib"),
+ (msg) => LogMessage (msg));
}
}
}
diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PostTrimmingAddKeepAlivesStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PostTrimmingAddKeepAlivesStep.cs
new file mode 100644
index 00000000000..e725b5714ec
--- /dev/null
+++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/PostTrimmingAddKeepAlivesStep.cs
@@ -0,0 +1,30 @@
+using System;
+using Java.Interop.Tools.Cecil;
+using Mono.Cecil;
+using Xamarin.Android.Tasks;
+
+namespace MonoDroid.Tuner;
+
+///
+/// Post-trimming version of AddKeepAlives that calls AddKeepAlivesHelper directly,
+/// matching the original ILLink behavior (no IsAndroidUserAssembly pre-filter).
+/// The helper has its own assembly-level guards (HasTypeReference, IsDotNetAndroidAssembly).
+///
+class PostTrimmingAddKeepAlivesStep : IAssemblyModifierPipelineStep
+{
+ readonly IMetadataResolver cache;
+ readonly Func getCorlibAssembly;
+ readonly Action logMessage;
+
+ public PostTrimmingAddKeepAlivesStep (IMetadataResolver cache, Func getCorlibAssembly, Action logMessage)
+ {
+ this.cache = cache;
+ this.getCorlibAssembly = getCorlibAssembly;
+ this.logMessage = logMessage;
+ }
+
+ public void ProcessAssembly (AssemblyDefinition assembly, StepContext context)
+ {
+ context.IsAssemblyModified |= AddKeepAlivesHelper.AddKeepAlives (assembly, cache, getCorlibAssembly, logMessage);
+ }
+}
diff --git a/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/StripEmbeddedLibrariesStep.cs b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/StripEmbeddedLibrariesStep.cs
new file mode 100644
index 00000000000..78f202b23c1
--- /dev/null
+++ b/src/Xamarin.Android.Build.Tasks/Linker/MonoDroid.Tuner/StripEmbeddedLibrariesStep.cs
@@ -0,0 +1,65 @@
+#nullable enable
+
+using System;
+using System.Linq;
+using Microsoft.Android.Build.Tasks;
+using Microsoft.Build.Utilities;
+using Mono.Cecil;
+using Xamarin.Android.Tasks;
+
+namespace MonoDroid.Tuner;
+
+class StripEmbeddedLibrariesStep : IAssemblyModifierPipelineStep
+{
+ readonly TaskLoggingHelper log;
+
+ public StripEmbeddedLibrariesStep (TaskLoggingHelper log)
+ {
+ this.log = log;
+ }
+
+ public void ProcessAssembly (AssemblyDefinition assembly, StepContext context)
+ {
+ if (MonoAndroidHelper.IsFrameworkAssembly (assembly))
+ return;
+ context.IsAssemblyModified |= StripEmbeddedLibraries (assembly, log);
+ }
+
+ internal static bool StripEmbeddedLibraries (AssemblyDefinition assembly, TaskLoggingHelper log)
+ {
+ bool modified = false;
+ 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);
+ modified = true;
+ }
+ }
+ }
+ return modified;
+ }
+
+ ///
+ /// 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;
+ }
+}
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 4be55630c91..84e68d8bf6f 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,7 +7,7 @@
-
+
<_RemoveRegisterFlag>$(MonoAndroidIntermediateAssemblyDir)shrunk\shrunk.flag
@@ -197,12 +197,6 @@
<_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="Microsoft.Android.Sdk.ILLink.PreserveJavaInterfaces" />
<_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" Type="MonoDroid.Tuner.FixAbstractMethodsStep" />
- <_TrimmerCustomSteps
- Condition=" '$(AndroidAddKeepAlives)' == 'true' "
- Include="$(_AndroidLinkerCustomStepAssembly)"
- AfterStep="CleanStep"
- Type="MonoDroid.Tuner.AddKeepAlivesStep"
- />
<_TrimmerCustomSteps
Condition=" '$(AndroidLinkResources)' == 'true' "
@@ -251,18 +245,20 @@
-
- <_StripEmbeddedLibrariesAssembly Include="@(ResolvedFileToPublish)" Condition=" '%(Extension)' == '.dll' " />
+ <_PostTrimmingAssembly Include="@(ResolvedFileToPublish)" Condition=" '%(Extension)' == '.dll' " />
-
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs b/src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs
new file mode 100644
index 00000000000..7a33ea3c7be
--- /dev/null
+++ b/src/Xamarin.Android.Build.Tasks/Tasks/PostTrimmingPipeline.cs
@@ -0,0 +1,87 @@
+#nullable enable
+
+using System.Collections.Generic;
+using System.IO;
+using Java.Interop.Tools.Cecil;
+using Microsoft.Android.Build.Tasks;
+using Microsoft.Build.Framework;
+using Mono.Cecil;
+using MonoDroid.Tuner;
+
+namespace Xamarin.Android.Tasks;
+
+///
+/// An MSBuild task that runs post-trimming assembly modifications in a single pass.
+///
+/// This opens each assembly once (via DirectoryAssemblyResolver with ReadWrite) and
+/// runs all registered steps on it, then writes modified assemblies in-place. Currently
+/// runs StripEmbeddedLibrariesStep and (optionally) AddKeepAlivesStep.
+///
+/// Runs in the inner build after ILLink but before ReadyToRun/crossgen2 compilation,
+/// so that R2R images are generated from the already-modified assemblies.
+///
+public class PostTrimmingPipeline : AndroidTask
+{
+ public override string TaskPrefix => "PTP";
+
+ [Required]
+ public ITaskItem [] Assemblies { get; set; } = [];
+
+ public bool AddKeepAlives { get; set; }
+
+ public bool Deterministic { get; set; }
+
+ public override bool RunTask ()
+ {
+ using var resolver = new DirectoryAssemblyResolver (
+ this.CreateTaskLogger (), loadDebugSymbols: true,
+ loadReaderParameters: new ReaderParameters { ReadWrite = true });
+ var cache = new TypeDefinitionCache ();
+
+ foreach (var assembly in Assemblies) {
+ var dir = Path.GetFullPath (Path.GetDirectoryName (assembly.ItemSpec) ?? "");
+ if (!resolver.SearchDirectories.Contains (dir)) {
+ resolver.SearchDirectories.Add (dir);
+ }
+ }
+
+ var steps = new List ();
+ steps.Add (new StripEmbeddedLibrariesStep (Log));
+ if (AddKeepAlives) {
+ // Memoize the corlib resolution so the attempt (and any error logging) happens at most once,
+ // regardless of how many assemblies/methods need KeepAlive injection.
+ AssemblyDefinition? corlibAssembly = null;
+ bool corlibResolutionAttempted = false;
+ steps.Add (new PostTrimmingAddKeepAlivesStep (cache,
+ () => {
+ if (!corlibResolutionAttempted) {
+ corlibResolutionAttempted = true;
+ try {
+ corlibAssembly = resolver.Resolve (AssemblyNameReference.Parse ("System.Private.CoreLib"));
+ } catch (AssemblyResolutionException ex) {
+ Log.LogErrorFromException (ex, showStackTrace: false);
+ }
+ }
+ return corlibAssembly;
+ },
+ (msg) => Log.LogDebugMessage (msg)));
+ }
+
+ foreach (var item in Assemblies) {
+ var assembly = resolver.GetAssembly (item.ItemSpec);
+ var context = new StepContext (item, item);
+ foreach (var step in steps) {
+ step.ProcessAssembly (assembly, context);
+ }
+ if (context.IsAssemblyModified) {
+ Log.LogDebugMessage ($" Writing modified assembly: {item.ItemSpec}");
+ assembly.Write (new WriterParameters {
+ WriteSymbols = assembly.MainModule.HasSymbols,
+ DeterministicMvid = Deterministic,
+ });
+ }
+ }
+
+ return !Log.HasLoggedErrors;
+ }
+}
diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/StripEmbeddedLibraries.cs b/src/Xamarin.Android.Build.Tasks/Tasks/StripEmbeddedLibraries.cs
deleted file mode 100644
index 7a65c4a8145..00000000000
--- a/src/Xamarin.Android.Build.Tasks/Tasks/StripEmbeddedLibraries.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-#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;
- }
-
-}
diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
index 577a607b4d7..c9157be3712 100644
--- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
+++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj
@@ -44,11 +44,15 @@
-
+
+
+
+
+