Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 0 additions & 56 deletions src/Microsoft.Android.Sdk.ILLink/StripEmbeddedLibraries.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<UsingTask TaskName="Xamarin.Android.Tasks.GetMonoPlatformJar" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
<UsingTask TaskName="Xamarin.Android.Tasks.RemoveRegisterAttribute" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
<UsingTask TaskName="Xamarin.Android.Tasks.GenerateProguardConfiguration" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />
<UsingTask TaskName="Xamarin.Android.Tasks.StripEmbeddedLibraries" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />

<PropertyGroup>
<_RemoveRegisterFlag>$(MonoAndroidIntermediateAssemblyDir)shrunk\shrunk.flag</_RemoveRegisterFlag>
Expand Down Expand Up @@ -203,7 +204,6 @@
Type="MonoDroid.Tuner.AddKeepAlivesStep"
/>
<!-- Custom steps that run after CleanStep -->
<_TrimmerCustomSteps Include="$(_AndroidLinkerCustomStepAssembly)" AfterStep="CleanStep" Type="MonoDroid.Tuner.StripEmbeddedLibraries" />
<_TrimmerCustomSteps
Condition=" '$(AndroidLinkResources)' == 'true' "
Include="$(_AndroidLinkerCustomStepAssembly)"
Expand Down Expand Up @@ -250,6 +250,22 @@
<Touch Files="$(_AndroidLinkFlag)" AlwaysCreate="true" />
</Target>

<!--
Strip embedded Android resources (.jar, native libs, etc.) from trimmed assemblies.
Runs in the inner build after ILLink but before ReadyToRun/crossgen2 compilation,
so R2R images are generated from already-stripped assemblies.
-->
<Target Name="_StripEmbeddedLibraries"
AfterTargets="ILLink"
Condition=" '$(PublishTrimmed)' == 'true' ">
<ItemGroup>
<_StripEmbeddedLibrariesAssembly Include="@(ResolvedFileToPublish)" Condition=" '%(Extension)' == '.dll' " />
</ItemGroup>
<StripEmbeddedLibraries
Assemblies="@(_StripEmbeddedLibrariesAssembly)"
Deterministic="$(Deterministic)" />
</Target>

<!-- Inject _TypeMapKind into the property cache -->
<Target Name="_SetTypemapProperties"
BeforeTargets="_CreatePropertiesCache">
Expand Down
116 changes: 116 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Tasks/StripEmbeddedLibraries.cs
Original file line number Diff line number Diff line change
@@ -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;

/// <summary>
/// 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.
/// </summary>
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<string> (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,
});
}
}

/// <summary>
/// Determines whether a resource should be stripped from the assembly.
/// Matches the same criteria as the old ILLink StripEmbeddedLibraries step.
/// </summary>
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;
}

}