Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 578
Run FixLegacyResourceDesigner before trimming#11084
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
70f7f3077de75de9edefdf0059fd64d4ed1924649e8be3817f12d74783a8f646e870ef4c4c0915e3ba1f432b1b2548ba357b726110dbbbee64205223629ccfdb7071577e20ffc1f3cebbcac9af78fc39b8e456231b8748b122e9a42f8b72eb28ccdfac02d09File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| #nullable enable | ||
| using System.Collections.Generic; | ||
| using System.IO; | ||
| using Java.Interop.Tools.Cecil; | ||
| using Microsoft.Android.Build.Tasks; | ||
| using Microsoft.Build.Framework; | ||
| using Microsoft.Build.Utilities; | ||
| using Mono.Cecil; | ||
| using MonoDroid.Tuner; | ||
| namespace Xamarin.Android.Tasks; | ||
| /// <summary> | ||
| /// Runs <see cref="FixLegacyResourceDesignerStep"/> on assemblies that are about to be | ||
| /// trimmed by ILLink. This rewrites library assemblies so their resource field accesses | ||
| /// (ldsfld) become calls to the designer assembly's property getters. | ||
| /// | ||
| /// Running this *before* ILLink means the trimmer sees the rewritten IL and can freely | ||
| /// trim unused designer types/fields. This avoids the need to root the entire designer | ||
| /// assembly during trimming (which causes an APK size regression). | ||
| /// | ||
| /// Modified assemblies are written to <see cref="OutputDirectory"/> rather than in-place, | ||
| /// to avoid mutating files in the shared NuGet cache or shared intermediate output paths. | ||
| /// </summary> | ||
| public class PreTrimmingFixLegacyDesigner : AndroidTask | ||
| { | ||
| public override string TaskPrefix => "PTD"; | ||
| [Required] | ||
| public ITaskItem [] Assemblies { get; set; } = []; | ||
| [Required] | ||
| public string TargetName { get; set; } = ""; | ||
| [Required] | ||
| public string OutputDirectory { get; set; } = ""; | ||
| public bool Deterministic { get; set; } | ||
| [Output] | ||
| public ITaskItem []? ModifiedAssemblies { get; set; } | ||
| public override bool RunTask () | ||
| { | ||
| Directory.CreateDirectory (OutputDirectory); | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 Consider cleaning the output directory at the start, or switching the swap target to use the // Clean stale prelink copies from previous runsif(Directory.Exists(OutputDirectory)){Directory.Delete(OutputDirectory,recursive:true);}Directory.CreateDirectory(OutputDirectory);Rule: Incremental build correctness (Postmortem Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems like | ||
| using var resolver = new DirectoryAssemblyResolver ( | ||
| this.CreateTaskLogger (), loadDebugSymbols: true); | ||
| foreach (var assembly in Assemblies) { | ||
| var dir = Path.GetFullPath (Path.GetDirectoryName (assembly.ItemSpec) ?? ""); | ||
| if (!resolver.SearchDirectories.Contains (dir)) { | ||
| resolver.SearchDirectories.Add (dir); | ||
| } | ||
| } | ||
| var linkContext = new MSBuildLinkContext (resolver, Log); | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 💡 Documentation — The removed code in // MSBuildLinkContext wraps the resolver; do not dispose it separately// as LinkContext.Dispose would double-dispose the resolver.varlinkContext=newMSBuildLinkContext(resolver,Log);Rule: Comments explain "why", not "what" (Postmortem | ||
| var fixLegacyStep = new FixLegacyResourceDesignerStep (); | ||
| fixLegacyStep.Initialize (linkContext); | ||
| var modified = new List<ITaskItem> (); | ||
| foreach (var item in Assemblies) { | ||
| // Match the filtering in FixLegacyResourceDesignerStep.ProcessAssembly: | ||
| // skip the main assembly and framework/BCL assemblies. | ||
| if (Path.GetFileNameWithoutExtension (item.ItemSpec) == TargetName) { | ||
| continue; | ||
| } | ||
| if (MonoAndroidHelper.IsFrameworkAssembly (item)) { | ||
| continue; | ||
| } | ||
| var assembly = resolver.GetAssembly (item.ItemSpec); | ||
| if (fixLegacyStep.ProcessAssemblyDesigner (assembly)) { | ||
| var outputPath = Path.Combine (OutputDirectory, Path.GetFileName (item.ItemSpec)); | ||
| Log.LogDebugMessage ($" Writing modified assembly: {outputPath}"); | ||
| assembly.Write (outputPath, new WriterParameters { | ||
| WriteSymbols = assembly.MainModule.HasSymbols, | ||
| DeterministicMvid = Deterministic, | ||
| }); | ||
| var outputItem = new TaskItem (outputPath); | ||
| item.CopyMetadataTo (outputItem); | ||
| outputItem.SetMetadata ("OriginalPath", item.ItemSpec); | ||
| modified.Add (outputItem); | ||
| } | ||
| } | ||
| ModifiedAssemblies = modified.ToArray (); | ||
| return !Log.HasLoggedErrors; | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 💡 Incremental builds — This swap uses an
Exists()check on the filesystem to decide whichResolvedFileToPublishitems to redirect toprelink/. If the stale prelink cleanup suggested inPreTrimmingFixLegacyDesigner.csis not adopted, an alternative fix here would be to persist_PreTrimmingModifiedAssemblyitems to a file (or use a response-file pattern) and read that back, so only assemblies actually modified in the current (or most recent) task run get swapped.Rule: Incremental build correctness