[TrimmableTypeMap] Extract typemap targets into dedicated files#10797
Conversation
Extract all typemap-related MSBuild targets from Xamarin.Android.Common.targets and Microsoft.Android.Sdk.ILLink.targets into a dedicated Xamarin.Android.TypeMap.Legacy.targets file, imported conditionally based on _AndroidTypeMapImplementation. Create empty stub files for the trimmable typemap implementation (Trimmable.targets, Trimmable.CoreCLR.targets, Trimmable.NativeAOT.targets). This is a pure refactoring — no new tasks, no new C# code, no behavioral changes. When _AndroidTypeMapImplementation != 'trimmable' (the default), the legacy targets are imported and the build pipeline is identical to before. Changes: - New: Xamarin.Android.TypeMap.Legacy.targets — all legacy typemap targets - _GenerateLegacyJavaCallableWrappers (JCW gen, ACW map, stubs, marshal methods) - _GenerateLegacyAndroidManifest (manifest + additional providers) - _GenerateLegacyTypeMappings (LLVM IR typemaps) - _SetLegacyTypemapProperties (_TypeMapKind) - _GetMonoPlatformJarPath (overrides empty stub) - _PrepareNativeAssemblySources (overrides empty stub) - _AddLegacyTypeManagerResources (TypeManager.java + mono.android.jar) - _RemoveRegisterAttribute (full version with RemoveRegisterAttribute task) - _CollectLegacyTypeMapFiles (FastDev archive) - New: Xamarin.Android.TypeMap.Trimmable.targets — dispatcher + validation stub - New: Xamarin.Android.TypeMap.Trimmable.CoreCLR.targets — empty stub - New: Xamarin.Android.TypeMap.Trimmable.NativeAOT.targets — empty stub - Modified: Common.targets — stripped of all legacy typemap task invocations, added empty stubs + conditional imports - Modified: ILLink.targets — added conditions to skip legacy ILLink steps when _AndroidTypeMapImplementation == 'trimmable' Fixes: #10779
…erateLegacyAndroidManifest GenerateMainAndroidManifest unregisters NativeCodeGenState from the build engine, so GenerateTypeMappings must retrieve it first. Add DependsOnTargets to ensure correct ordering between the two AfterTargets targets.
d996077 to
c9ab4a4
Compare
Move _PrepareLinking, _FixRootAssembly, and _TouchAndroidLinkFlag from Microsoft.Android.Sdk.ILLink.targets into Xamarin.Android.TypeMap.Legacy.targets. This eliminates scattered _AndroidTypeMapImplementation != 'trimmable' conditions in ILLink.targets — the conditions are now implicit since Legacy.targets is only imported when _AndroidTypeMapImplementation is not 'trimmable'.
c9ab4a4 to
3a234cb
Compare
| <None Include="Xamarin.Android.TypeMap.LlvmIr.targets"> | ||
| <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
| </None> |
There was a problem hiding this comment.
New files we've been naming Microsoft.Android.Sdk.*.targets and putting in the targets folder. The Xamarin.* ones are old.
You might also check, if we can have a wildcard, where you don't need to add any new @(None) items.
There was a problem hiding this comment.
Done — renamed to Microsoft.Android.Sdk.TypeMap.*.targets and moved to targets/ in the next commit. Also switched to a wildcard @(None) pattern.
Address PR feedback: - Rename Xamarin.Android.TypeMap.*.targets -> Microsoft.Android.Sdk.TypeMap.*.targets - Move files to Microsoft.Android.Sdk/targets/ (new file convention) - Remove @(None) entries (handled by _CopyNetSdkTargets wildcard) - Delete Microsoft.Android.Sdk.ILLink.targets (moved _LinkAssemblies to Common.targets) - Add _ValidateAndroidTypeMapImplementation target - Add _GenerateJavaStubs stub in Trimmable.targets - Fix UsingTask references to use $(_XamarinAndroidBuildTasksAssembly) - Fix ILLink DLL paths for targets/ directory context
There was a problem hiding this comment.
Pull request overview
This PR extracts all typemap-related MSBuild targets from Xamarin.Android.Common.targets and Microsoft.Android.Sdk.ILLink.targets into dedicated, conditionally-imported files to enable future addition of a "trimmable" typemap implementation. This is a pure refactoring with no new functionality.
Changes:
- Extracted legacy typemap targets (llvm-ir and managed implementations) into
Microsoft.Android.Sdk.TypeMap.LlvmIr.targets - Created stub files for future trimmable typemap implementation:
Trimmable.targets,Trimmable.CoreCLR.targets, andTrimmable.NativeAOT.targets - Moved shared
_LinkAssembliestarget toCommon.targetsand deletedMicrosoft.Android.Sdk.ILLink.targets
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
Xamarin.Android.Common.targets |
Removed typemap UsingTask declarations, removed inline targets (_GenerateJavaStubs, _GetMonoPlatformJarPath, etc.), added conditional imports for LlvmIr/Trimmable targets, moved _LinkAssemblies here, gutted _RemoveRegisterAttribute to base implementation |
Microsoft.Android.Sdk.TypeMap.LlvmIr.targets |
New file containing all legacy typemap logic: UsingTask declarations, _GenerateJavaStubs, _PrepareLinking, _GetMonoPlatformJarPath, _PrepareNativeAssemblySources, _AddTypeManagerResources, _RemoveRegisterAttribute override, _CollectTypeMapFiles, ILLink customization |
Microsoft.Android.Sdk.TypeMap.Trimmable.targets |
New stub file with runtime-specific imports, runtime validation, and empty _GenerateJavaStubs placeholder |
Microsoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets |
Empty stub for future CoreCLR-specific trimmable implementation |
Microsoft.Android.Sdk.TypeMap.Trimmable.NativeAOT.targets |
Empty stub for future NativeAOT-specific trimmable implementation |
Microsoft.Android.Sdk.ILLink.targets |
Deleted - all content moved to LlvmIr.targets and Common.targets |
Microsoft.Android.Sdk.After.targets |
Removed import of deleted ILLink.targets file |
...droid.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.LlvmIr.targets
Show resolved
Hide resolved
...droid.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.LlvmIr.targets
Show resolved
Hide resolved
...id.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.targets
Show resolved
Hide resolved
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
…e stub - Restore missing TypeMappingStep ILLink custom step for managed typemap implementation (used by NativeAOT) - Add proper DependsOnTargets, Inputs/Outputs, and stamp file to the trimmable _GenerateJavaStubs stub for incremental build support - Add TODO comment about manifest extraction (#10807): both GenerateMainAndroidManifest and GenerateAdditionalProviderSources depend on NativeCodeGenState and need to be decoupled before they can be shared across typemap paths
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Re: NativeAOT test failures — the |
The TypeMap imports must be last in Common.targets so that their target overrides (e.g. _RemoveRegisterAttribute with Inputs/Outputs) take precedence over the base definitions. Previously, the imports were at line 388 while the base _RemoveRegisterAttribute was at line 1915, causing the base version (without Inputs/Outputs/Touch) to override the LlvmIr version, breaking incremental builds.
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
jonathanpeppers
left a comment
There was a problem hiding this comment.
Xamarin.Android-PR is green, but weird dotnet-public is running again.
I'll merge shortly, we don't have to wait.
| </Target> | ||
|
|
||
| <!-- ILLink customization: custom trimmer steps, root descriptors, etc. --> | ||
| <Target Name="_PrepareLinking" |
There was a problem hiding this comment.
Why was this moved to TypeMap.LlvmIr.targets? It looks like general ILLink logic, not specifically related to type map. @simonrozsival
There was a problem hiding this comment.
I wanted to make room for changes to ILLink configuration for the new typemap. It's quite likely that some of the configuration will be brought back in the next steps. If there's too much duplication in the ILLink config between the two typemap variants, we can add the ILLink.targest file back.
There was a problem hiding this comment.
Thanks - I think it would make sense to factor this so that the common logic not related to type maps is shared if possible. Otherwise this introduces another place where the configs can drift, which would increase the work it takes to migrate away from custom steps.
There was a problem hiding this comment.
The Trimmable Type Map won't have any custom steps. At the same time, I'm not sure if we will be able to really remove the custom steps from the legacy typemap. We will likely be able to generate (huge) ILLink descriptors XML files that would replace the custom marking logic, but I'm not sure if that's worth the effort. We discussed using ILLink from .NET 10 with Mono in .NET 11. Do you think that could be a viable option? Mono will still need to use .dlls without runtime async, so I would expect one version old ILLink would be able to trim these assemblies just fine? For CoreCLR, we would use .NET 11 ILLink and for NativeAOT there won't be any ILLink step in the build pipeline.
There was a problem hiding this comment.
We discussed using ILLink from .NET 10 with Mono in .NET 11. Do you think that could be a viable option?
It may be viable, but it seems like a fragile setup. Any new language features that show up in .NET 11 won't necessarily be supported with the .NET 10 ILLink, unless we continue adding features in servicing, and at that point we might as well consider shipping a separate .NET 11 illink for mono.

Summary
Extracts all typemap-related MSBuild targets from
Xamarin.Android.Common.targetsandMicrosoft.Android.Sdk.ILLink.targetsinto dedicated files, conditionally imported based on_AndroidTypeMapImplementation. This is a pure refactoring to enable future addition of a "trimmable" typemap implementation (see #10779).Changes
New files
Microsoft.Android.Sdk.TypeMap.LlvmIr.targets— All current typemap targets extracted from Common.targets and ILLink.targets: JCW generation, manifest generation, typemap generation, ILLink customization (_PrepareLinking,_FixRootAssembly,_TouchAndroidLinkFlag), mono.android.jar handling, TypeManager.java creation,_RemoveRegisterAttribute, FastDev type map collectionMicrosoft.Android.Sdk.TypeMap.Trimmable.targets— Dispatcher stub that imports CoreCLR/NativeAOT sub-targets + runtime validation + empty_GenerateJavaStubsplaceholderMicrosoft.Android.Sdk.TypeMap.Trimmable.CoreCLR.targets— Empty stubMicrosoft.Android.Sdk.TypeMap.Trimmable.NativeAOT.targets— Empty stubModified files
Xamarin.Android.Common.targets— Removed typemap task invocations (moved to LlvmIr.targets), added conditional imports, added_ValidateAndroidTypeMapImplementationand_LinkAssembliestargetsMicrosoft.Android.Sdk.After.targets— RemovedILLink.targetsimport (no longer needed)Deleted files
Microsoft.Android.Sdk.ILLink.targets— All content moved toLlvmIr.targetsandCommon.targetsDesign decisions
Microsoft.Android.Sdk.*naming convention and live in thetargets/directory_LinkAssemblies(generic orchestration) moved toCommon.targetssince it applies to all typemap implementations_PrepareLinking, etc.) moved toLlvmIr.targetssince they are specific to the current typemap implementation_ValidateAndroidTypeMapImplementationvalidates the property value at build time (valid:llvm-ir,managed,trimmable)Closes to #10779