Skip to content

Avoid passing satellite assemblies to post-trimming pipeline #11085

Description

@sbomer

This content was created with assistance from AI.

The _PostTrimmingPipeline target in Microsoft.Android.Sdk.TypeMap.LlvmIr.targets includes all .dll files from @(ResolvedFileToPublish) without filtering out satellite assemblies:

<_PostTrimmingAssemblyInclude="@(ResolvedFileToPublish)"Condition=" '%(Extension)' == '.dll' " />

After ILLink runs, linked assemblies have their paths updated to the per-RID intermediate output directory, but satellite assemblies (e.g., ar/Microsoft.Maui.Controls.resources.dll) are not processed by ILLink and retain their original paths in the shared NuGet package cache. The PostTrimmingPipeline task opens every assembly with ReadWrite = true via DirectoryAssemblyResolver, which takes an exclusive file lock. When _AndroidBuildRuntimeIdentifiersInParallel is true (the default), multiple inner builds each run _PostTrimmingPipeline and try to exclusively open the same satellite assemblies from the shared cache simultaneously, causing IOException: file being used by another process.

This was observed in dotnet/maui CI on PR dotnet/maui#34552 (build) where SimpleTemplateTest.Build and SimpleTemplateTest.BuildWithMauiVersion integration tests consistently fail on Windows with TrimMode=partial in Release configuration. The failures appeared with the Android SDK version bump from 36.1.99-ci.main.217 to 36.99.0-ci.main.53.

Suggested fix

The .NET SDK already marks ILLink-processed assemblies with PostprocessAssembly=true metadata (set by _ComputeAssembliesToPostprocessOnPublish in Microsoft.NET.Publish.targets). This metadata survives the ILLink Remove/Include cycle because MSBuild item transforms preserve metadata. Satellite assemblies never receive this metadata. The fix is to filter on it:

<_PostTrimmingAssemblyInclude="@(ResolvedFileToPublish)"Condition=" '%(Extension)' == '.dll' and '%(PostprocessAssembly)' == 'true' " />

None of the pipeline steps (CheckForObsoletePreserveAttribute, StripEmbeddedLibraries, RemoveResourceDesigner, FixAbstractMethods, AddKeepAlives) need to process satellite assemblies — they operate on types, native embedded resources, and method bodies.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

needs-triageIssues that need to be assigned.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions