Skip to content
34 changes: 34 additions & 0 deletions Documentation/docs-mobile/building-apps/build-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -1903,6 +1903,40 @@ ReadyToRun compilation is composite by default. See
[`$(MauiEnableFullReadyToRun)`](#mauienablefullreadytorun) to opt in to
full ReadyToRun.

For ARM64, .NET for Android defaults crossgen2 to:

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.

We have these defaults in crossgen2 for all other OSes. If the defaults in crossgen2 do not work well for Android, we should fix it in crossgen2. I do not think we want to have these low-level defaults spread over multiple places.

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.

We may want to drop rcpc2 from the optimistic set for all OSes. It is relatively minor optimization that makes a lot of R2R methods rejected on older hardware.


```text
--instruction-set:-optimistic,aes,crc,dotprod,lse,rcpc,rdma,sha1,sha2
```

This disables automatic optimistic instruction-set additions and explicitly
enables the listed features, excluding RCPC2 without requiring RCPC2 to be
absent. The listed features become baseline requirements for the precompiled
image, rather than optional optimistic features. Devices without a required
feature can reject the image's ReadyToRun code and fall back to JIT compilation.

Other CPU architectures default to `--instruction-set:-optimistic`, which
disables automatic optimistic instruction-set additions while retaining the
normal baseline requirements. Neither policy disables hardware-specific
optimizations in the JIT or tiered compilation.

An explicit `--instruction-set` option in
`$(PublishReadyToRunCrossgen2ExtraArgs)` overrides this default.
An instruction-set option in
`$(PublishReadyToRunCrossgen2CompositeExtraArgs)` also opts the entire
build out of this default, including assemblies in
`@(PublishReadyToRunCompositeExclusions)`. The .NET SDK concatenates the
normal and composite arguments for the composite image, and crossgen2
does not accept multiple `--instruction-set` options. The opt-out applies
even when `$(PublishReadyToRunComposite)` is `false`.

To apply an instruction-set policy to both the composite image and
excluded assemblies, set it in
`$(PublishReadyToRunCrossgen2ExtraArgs)`, not in the composite-only
arguments. For example, `--instruction-set:-optimistic` in the normal
arguments keeps both conservative. Do not specify the option in both
argument properties.

For more information, see
[Runtimes and compilation in .NET MAUI][maui-runtimes-compilation].

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@ This file contains the CoreCLR-specific MSBuild logic for .NET for Android.
<AllowReadyToRunWithoutRuntimeIdentifier Condition=" '$(PublishReadyToRun)' == 'true' and '$(RuntimeIdentifiers)' != '' ">true</AllowReadyToRunWithoutRuntimeIdentifier>
</PropertyGroup>

<!-- Exclude RCPC2 from ARM64 R2R without asserting that the feature must be absent.
The explicit list requires its other features; keep other architectures conservative.
Resolve this after project/package imports have supplied their crossgen2 arguments. -->
<Target Name="_AndroidSetReadyToRunInstructionSet"
BeforeTargets="_PrepareForReadyToRunCompilation"
Condition=" '$(AndroidApplication)' == 'true' and '$(PublishReadyToRun)' == 'true' and '$(_AndroidUseOptimisticReadyToRunInstructionSet)' != 'true' ">
<PropertyGroup Condition=" !$(PublishReadyToRunCrossgen2ExtraArgs.Contains('--instruction-set')) and !$(PublishReadyToRunCrossgen2CompositeExtraArgs.Contains('--instruction-set')) ">
Comment thread
simonrozsival marked this conversation as resolved.
<PublishReadyToRunCrossgen2ExtraArgs Condition=" '$(RuntimeIdentifier)' == 'android-arm64' ">$(PublishReadyToRunCrossgen2ExtraArgs);--instruction-set:-optimistic,aes,crc,dotprod,lse,rcpc,rdma,sha1,sha2</PublishReadyToRunCrossgen2ExtraArgs>
<PublishReadyToRunCrossgen2ExtraArgs Condition=" '$(RuntimeIdentifier)' != 'android-arm64' ">$(PublishReadyToRunCrossgen2ExtraArgs);--instruction-set:-optimistic</PublishReadyToRunCrossgen2ExtraArgs>
</PropertyGroup>
</Target>

<!-- Default feature switches -->
<ItemGroup>
<RuntimeHostConfigurationOption Include="Microsoft.Android.Runtime.RuntimeFeature.IsMonoRuntime"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ namespace Xamarin.Android.Build.Tests
[Parallelizable (ParallelScope.Children)]
public partial class BuildTest2 : BaseTest
{
const string Arm64ReadyToRunInstructionSet = "--instruction-set:-optimistic,aes,crc,dotprod,lse,rcpc,rdma,sha1,sha2";

static object [] MarshalMethodsDefaultStatusSource = new object [] {
new object[] {
/* isRelease */ true,
Expand Down Expand Up @@ -75,8 +77,10 @@ public void BasicApplicationPublishReadyToRun ([Values] bool isComposite, [Value
proj.SetProperty ("AndroidEnableAssemblyCompression", "false");
proj.SetProperty ("PublishReadyToRunComposite", isComposite.ToString ());

var b = CreateApkBuilder ();
using var b = CreateApkBuilder ();
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
var expectedInstructionSet = rid == "android-arm64" ? Arm64ReadyToRunInstructionSet : "--instruction-set:-optimistic";
StringAssertEx.Contains (expectedInstructionSet, b.LastBuildOutput);

var assemblyName = proj.ProjectName;
var apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, rid, $"{proj.PackageName}-Signed.apk");
Expand Down
Loading