Skip to content

[TrimmableTypeMap] Fix stale per-assembly typemap output invalidation #11489

@simonrozsival

Description

@simonrozsival

Part of #10958.

The current trimmable typemap task has target-level MSBuild incrementality, but the in-task per-assembly typemap write skip appears too coarse. GenerateTrimmableTypeMap.WriteAssembliesToDisk() decides whether to skip writing each non-root typemap DLL by checking only whether the output timestamp is newer than the source assembly timestamp.

That can become stale when _GenerateTrimmableTypeMap reruns because a non-assembly input changed, while the individual source assembly timestamp did not. Examples include manifest/rooting inputs, package naming policy, Debug vs Release shared-universe mode, $(_AndroidBuildPropertiesCache) inputs, and $(_AndroidTrimmableTypeMapMaxArrayRank).

Current locations

  • src/Xamarin.Android.Build.Tasks/Tasks/GenerateTrimmableTypeMap.cs
    • WriteAssembliesToDisk(...)
    • IsUpToDate(...)
  • src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.Trimmable.targets
    • _GenerateTrimmableTypeMap target Inputs includes non-assembly inputs that can invalidate generation.

Suggested fix

Prefer correctness over clever timestamp checks:

  • Either always pass the generated stream through Files.CopyIfStreamChanged(...) for per-assembly typemap DLLs, or extend the skip logic so it accounts for every input that can affect the generated bytes.
  • Keep timestamp-preserving behavior when bytes are unchanged.
  • Ensure the root _Microsoft.Android.TypeMaps.dll is regenerated when its inputs change, not only when a per-assembly file timestamp was touched.

Acceptance criteria

  • A rebuild triggered only by a relevant non-assembly typemap input cannot leave stale per-assembly typemap DLLs behind.
  • Timestamp-preserving behavior remains for true no-content-change cases.
  • Add targeted tests covering at least one non-assembly input change that affects generated output.

Metadata

Metadata

Assignees

No one assigned

    Labels

    copilot`copilot-cli` or other AIs were used to author thistrimmable-type-map

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions