Skip to content

[build] Remove unused System.IO.Hashing from runtime packs and build tasks - #13197

Merged
simonrozsival merged 2 commits into
mainfrom
simonrozsival-system-io-hashing-packaging-analysis
Oct 20, 2026
Merged

simonrozsival merged 2 commits into
mainfrom
simonrozsival-system-io-hashing-packaging-analysis

Conversation

@simonrozsival

Copy link
Copy Markdown
Member

After removing the reflection-based managed typemap (#12134) and legacy LLVM-IR typemap (#12889), several System.IO.Hashing references and helpers are no longer used:

  • Runtime packs: Remove unused System.IO.Hashing package references and runtime pack items from Mono.Android.csproj, Microsoft.Android.Runtime.NativeAOT.csproj, and Microsoft.Android.Runtime.Managed.proj.
  • Build tasks & test helpers:
    • Remove dead GetXxHash and Utf16StringToBytes helpers from MonoAndroidHelper.Basic.cs and drop the now-unused System.IO.Hashing reference from Xamarin.ProjectTools.csproj.
    • Move HashJavaName into tools/tmt/XamarinAppReleaseDSO_V2.cs (its only remaining caller), inline the two remaining Crc32 helpers into AssemblyStoreGenerator and CoreClrBootstrapBuilder, and delete src/Xamarin.Android.Build.Tasks/Utilities/TypeMapHelper.cs (along with its unsafe string-encoding helper and AllowUnsafeBlocks in tmt.csproj).
    • Replace XxHash128 with SHA256 in MibcProfileWriter.ContentId.

Validation

  • ./dotnet-local.sh build src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj -v minimal — Passed
  • ./dotnet-local.sh build src/Microsoft.Android.Build.Tasks/Microsoft.Android.Build.Tasks.csproj -v minimal — Passed
  • ./dotnet-local.sh build src/Microsoft.Android.Runtime.NativeAOT/Microsoft.Android.Runtime.NativeAOT.csproj -v minimal — Passed
  • ./dotnet-local.sh build src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Xamarin.ProjectTools.csproj -v minimal — Passed
  • ./dotnet-local.sh build tools/tmt/tmt.csproj -v minimal — Passed
  • ./dotnet-local.sh test tests/Microsoft.Android.Build.BaseTasks-Tests/Microsoft.Android.Build.BaseTasks-Tests.csproj -v minimal — Passed (124 passed, 4 skipped)
  • ./dotnet-local.sh test src/Microsoft.Android.Build.Tasks/Tests/Microsoft.Android.Build.Tasks.Tests/Microsoft.Android.Build.Tasks.Tests.csproj --filter "FullyQualifiedName~GenerateTrimmableTypeMapTests|FullyQualifiedName~CoreClrBootstrapBlobTests|FullyQualifiedName~DlopenAssemblyStoreGeneratorTests|FullyQualifiedName~ZipArchiveExTests" -v minimal — Passed (39 passed)
  • ./dotnet-local.sh test bin/TestDebug/net10.0/Xamarin.Android.Build.Tests.dll --filter "FullyQualifiedName~GenerateNativeApplicationConfigSourcesTests|FullyQualifiedName~GenerateMibcProfileTests" -v minimal — Passed (7 passed)

Pull Request
title and
description
should follow the
commit-messages.md workflow documentation, and in particular should include:

  • Useful description of why the change is necessary.
  • Links to issues fixed
  • Unit tests

simonrozsival and others added 2 commits October 19, 2026 16:53
…tasks

After removing the reflection-based managed typemap (#12134) and legacy
LLVM-IR typemap (#12889), several System.IO.Hashing references and
helpers are no longer needed:

- Remove unused System.IO.Hashing package references and runtime pack
  items from Mono.Android.csproj, Microsoft.Android.Runtime.NativeAOT.csproj,
  and Microsoft.Android.Runtime.Managed.proj.
- Remove dead GetXxHash and Utf16StringToBytes helpers from
  MonoAndroidHelper.Basic.cs and drop the now-unused System.IO.Hashing
  reference from Xamarin.ProjectTools.csproj.
- Move HashJavaName from TypeMapHelper.cs into tools/tmt (its only
  remaining caller), dropping the linked TypeMapHelper.cs and
  AllowUnsafeBlocks from tmt.csproj.
- Replace XxHash128 with SHA256 in MibcProfileWriter.ContentId.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Inline the two remaining CRC32 helpers into AssemblyStoreGenerator and
CoreClrBootstrapBuilder and remove TypeMapHelper.cs along with its
unsafe string-encoding helper.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 19, 2026 14:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

Hash compatibility is preserved, reported focused validation passed, and only an optional allocation improvement remains.

1 open issue
What changed in this PR

Removes obsolete hashing dependencies and helpers following the managed and LLVM-IR typemap removals.

Changes:

  • Removes unused runtime-pack and test-helper dependencies.
  • Moves remaining hash helpers to their consumers.
  • Uses SHA256 for deterministic MIBC content IDs.
File Description
tools/​tmt/​XamarinAppReleaseDSO_V2.cs Localizes Java-name hashing.
tools/​tmt/​tmt.csproj Removes shared helper and unsafe setting.
src/​Xamarin.Android.Build.Tasks/​Utilities/​TypeMapHelper.cs Deletes obsolete shared helpers.
src/​Xamarin.Android.Build.Tasks/​Utilities/​MonoAndroidHelper.Basic.cs Removes unused hashing utilities.
src/​Xamarin.Android.Build.Tasks/​Utilities/​MibcProfileWriter.cs Switches content hashing to SHA256.
src/​Xamarin.Android.Build.Tasks/​Utilities/​CoreClrBootstrapBuilder.cs Localizes library-name hashing.
src/​Xamarin.Android.Build.Tasks/​Utilities/​AssemblyStoreGenerator.cs Localizes assembly-name hashing.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.ProjectTools/​Xamarin.ProjectTools.csproj Removes unused package reference.
src/​native/​clr/​include/​runtime-base/​crc32.hh Updates helper names in a comment.
src/​Mono.Android/​Mono.Android.csproj Removes hashing dependency and copy item.
src/​Microsoft.Android.Runtime.NativeAOT/​Microsoft.Android.Runtime.NativeAOT.csproj Removes unused hashing dependency.
build-tools/​create-packs/​Microsoft.Android.Runtime.Managed.proj Stops packaging the hashing assembly.

Review effort: Balanced

@simonrozsival

Copy link
Copy Markdown
Member Author

/review

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

✅ Android PR Reviewer completed successfully!

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • azcliprod.blob.core.windows.net

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "azcliprod.blob.core.windows.net"

See Network Configuration for more information.

Generated by Android PR Reviewer for #13197

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM with one performance suggestion

Findings: 0 errors · 0 warnings · 1 suggestion

The runtime-pack dependency removal is consistent across the pack project, Mono.Android, and NativeAOT project. The localized CRC/XXHash implementations preserve the previous sentinel and encoding behavior, and the SHA-256 MIBC content ID remains deterministic and provides the 20+ bytes required by BlobContentId.FromHash.

CI had no failures at review time: 40 of 42 GitHub checks had completed successfully, with one emulator lane still running and the aggregate dotnet-android check queued.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • azcliprod.blob.core.windows.net

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "azcliprod.blob.core.windows.net"

See Network Configuration for more information.

Generated by Android PR Reviewer for #13197 · copilot · gpt56 · 127.6 AIC · ⌖ 11.1 AIC · ⊞ 26.4K
Comment /review to run again

@simonrozsival simonrozsival added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Oct 20, 2026
@simonrozsival
simonrozsival enabled auto-merge (squash) October 20, 2026 15:00
Comment on lines -560 to 562
// This is only a content fingerprint, so a non cryptographic hash is fine, and unlike
// System.Security.Cryptography the System.IO.Hashing APIs are span based on netstandard2.0.
int byteCount = Encoding.UTF8.GetByteCount (fingerprint);
Span<byte> bytes = byteCount <= TypeMapHelper.StackallocThresholdBytes
? stackalloc byte [byteCount]
: new byte [byteCount];
TypeMapHelper.GetBytes (fingerprint, Encoding.UTF8, bytes);

// BlobContentId.FromHash turns hash bytes into an MVID and timestamp for us, including the
// RFC 4122 version and variant bits and the byte order of the Guid fields. It reads 20
// bytes: 0..16 become the MVID and 16..20 become the timestamp. XxHash128 only produces
// 16, so the timestamp slot repeats the first four rather than hashing the input again.
// This cannot be a stackalloc: FromHash only overloads on byte[] and ImmutableArray<byte>.
var hash = new byte [20];
XxHash128.Hash (bytes, hash.AsSpan (0, 16));
hash.AsSpan (0, 4).CopyTo (hash.AsSpan (16));
using var sha256 = SHA256.Create ();
byte[] hash = sha256.ComputeHash (Encoding.UTF8.GetBytes (fingerprint));
return BlobContentId.FromHash (hash);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did we lose the stackalloc above? seems like we could keep that partially?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mibc is Release mode, so probably OK.

@simonrozsival
simonrozsival merged commit 9e66448 into main Oct 20, 2026
42 checks passed
@simonrozsival
simonrozsival deleted the simonrozsival-system-io-hashing-packaging-analysis branch October 20, 2026 15:04
simonrozsival added a commit that referenced this pull request Oct 27, 2026
…oid.Build.Tasks (#13199)

Context: bf732908d0250966278042dc63a5f6f7ec2ca614
Context: 12c2d57
Context: 9e66448
Context: fa7d557
Context: a3c24de

`Xamarin.Android.Build.Tasks.dll` targets `netstandard2.0` so that MSBuild tasks can load in both .NET Framework (`MSBuild.exe` in Visual Studio) and .NET (`dotnet build`).  Because `netstandard2.0` does not include `System.IO.Hashing` in the shared framework, referencing `System.IO.Hashing` from `Xamarin.Android.Build.Tasks.csproj` deposits the `netstandard2.0` flavor of `System.IO.Hashing.dll` (whose `Span<T>` overloads bind to `System.Memory`) into the SDK's `tools/` directory.  As noted in bf73290, `net11.0` tasks had to be placed in `tools/net/Microsoft.Android.Build.Tasks.dll` so they would not resolve the `netstandard2.0` `System.IO.Hashing.dll` and fail with `MissingMethodException`.

After commits 9e66448 (#13197) and a3c24de (#13198) removed unused hashing helpers and moved `<CreateAssemblyStore/>` to `Microsoft.Android.Build.Tasks.dll`, `<GenerateNativeApplicationConfigSources/>` (via `CoreClrBootstrapBuilder`) was the last remaining consumer of `System.IO.Hashing.Crc32` in `Xamarin.Android.Build.Tasks.dll`.

Move `<GenerateNativeApplicationConfigSources/>` and its supporting types from `src/Xamarin.Android.Build.Tasks` (`netstandard2.0`) to `src/Microsoft.Android.Build.Tasks` (`net11.0`) so `Xamarin.Android.Build.Tasks.dll` no longer needs `System.IO.Hashing`:

  * Move `GenerateNativeApplicationConfigSources`, `CoreClrBootstrapBuilder`, `RuntimePropertiesParser`, and `BundleConfigSplitConfigsChecker` to `src/Microsoft.Android.Build.Tasks/` under `namespace Microsoft.Android.Tasks`.
  * Compute DSO cache entry hashes in `CoreClrBootstrapBuilder.Write()` directly via `System.IO.Hashing.Crc32.HashToUInt32()`, and add an explicit `System.IO.Hashing` `<PackageReference/>` to `Microsoft.Android.Build.Tasks.csproj`.
  * Remove the `CoreClrBootstrapBlob.cs` and `EnvironmentBuilder.cs` source links from `Xamarin.Android.Build.Tasks.csproj`, as all callers now reside in `Microsoft.Android.Build.Tasks.dll`.
  * Move `MonoAndroidHelper.GetAssemblyCulture()`, `ParseAndroidRuntime()`, and `GetNormalizedNativeLibraryName()` into the shared `MonoAndroidHelper.Assemblies.cs` file (using `.IsNullOrEmpty()` so `#nullable enable` compiles cleanly on `netstandard2.0` as well as `net11.0`), and move `ELFHelper.IsJniLibrary()` into `CoreClrBootstrapBuilder` while removing unused symbol-lookup helpers from `ELFHelper`.
  * Define `PackageNamingPolicy` in `Microsoft.Android.Tasks` so `Microsoft.Android.Build.Tasks.csproj` remains self-contained without referencing `Java.Interop.Tools.TypeNameMappings`.
  * Update `Xamarin.Android.Common.targets` to register `Microsoft.Android.Tasks.GenerateNativeApplicationConfigSources` from `$(_MicrosoftAndroidBuildTasksAssembly)` using the conditional `Full` (`TaskHostFactory`) / `Core` `Runtime="NET"` `<UsingTask/>` pattern from fa7d557 (#13195), and update `$(_AndroidCoreClrBootstrapTaskAssembly)` in the `_AndroidGenerateCoreClrBootstrapInputs` target to track `$(_MicrosoftAndroidBuildTasksAssembly)`.
  * Move `GenerateNativeApplicationConfigSourcesTests`, `RuntimePropertiesParserTests`, and `EnvironmentBuilderTests` to `Microsoft.Android.Build.Tasks.Tests`, generating synthetic 32-bit (`AndroidTargetArch.Arm`) and 64-bit (`AndroidTargetArch.Arm64`) ELF JNI libraries via `AssemblyStoreElfWriter` and `ELFReader` so the tests run standalone without requiring a native build of `libtest-jni-library.so`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants