Skip to content

Commit

Permalink
[One .NET] fix AOT builds with different settings (#6556)
Browse files Browse the repository at this point in the history
Building a .NET 6 `Release` app with `UseInterpreter=true` and
`RunAOTCompilation=true` would fail with:

	Microsoft.Android.Sdk.Aot.targets(71,5): Unknown Mode value: Interpreter. 'Mode' must be one of: Normal,JustInterp,Full,FullInterp,Hybrid,LLVMOnly,LLVMOnlyInterp

Reviewing [Mono's AOT code][0]:

	public enum MonoAotMode
	{
	    Normal,
	    JustInterp,
	    Full,
	    FullInterp,
	    Hybrid,
	    LLVMOnly,
	    LLVMOnlyInterp
	}

There does not appear to be a mode for `Normal` + `Interp`.  So let's
instead have AOT take precedence over `$(UseInterpreter)`.
On Android, `$(UseInterpreter)` is a Debug-mode setting for
[Hot Reload][1]; the *expectation* is that AOT won't be enabled in
Debug config builds as Debug builds should be "fast" while AOT builds
are *slow*, so if AOT is explicitly enabled, *presumably* the
developer doesn't want the Interpreter.

To inform developers of this change, we now emit an XA0119 warning
when both `$(UseInterpreter)`=true and `$(RunAOTCompilation)`=true:

	dotnet build -p:UseInterpreter=true -p:RunAOTCompilation=true
	…
	warning XA0119: Disabling the interpreter;
	  using the interpreter and AOT at the same time is not supported.
	  Use the interpreter for hot reload support in Debug configurations and
	  AOT for Release configurations.

While testing this new priority order, we found that building a
.NET 6 `Debug` config app with `$(RunAOTCompilation)`=true would
fail with:

	Microsoft.Android.Sdk.Aot.targets(49,5): error MSB4044:
	The "GetAotAssemblies" task was not given a value for the required parameter "AndroidApiLevel".

This is because the linker was skipped, particularly this target:

	<Target Name="_PrepareLinking"
	    Condition=" '$(PublishTrimmed)' == 'true' "
	    AfterTargets="ComputeResolvedFilesToPublishList"
	    DependsOnTargets="GetReferenceAssemblyPaths;_CreatePropertiesCache">

The `_CreatePropertiesCache` target didn't run, and so we have some
empty properties in this case.

We can simply add `_CreatePropertiesCache` to the `_AndroidAot` MSBuild
target's `DependsOnTargets` to solve this issue.

[0]: https://github.com/dotnet/runtime/blob/60edc0bdafce1849fec19e3ec4f766074de50fc3/src/tasks/AotCompilerTask/MonoAOTCompiler.cs#L1064-L1073
[1]: https://docs.microsoft.com/visualstudio/debugger/hot-reload
  • Loading branch information
jonathanpeppers authored Dec 10, 2021
1 parent 2773e1f commit 513f613
Show file tree
Hide file tree
Showing 19 changed files with 128 additions and 2 deletions.
7 changes: 7 additions & 0 deletions Documentation/guides/messages/xa0119.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,21 @@ Remove the following options from `Debug` configurations:
* App Bundles
* `<AndroidPackageFormat>aab</AndroidPackageFormat>`

Remove the following from `Release` configurations:

* Hot Reload support
* `<UseInterpreter>true</UseInterpreter>`

*DO* use the following options for `Debug` configurations:

* `<AndroidLinkMode>None</AndroidLinkMode>`
* `<EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk>`
* `<UseInterpreter>true</UseInterpreter>`

*DO* use the following options for `Release` configurations:

* `<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>`
* `<AotAssemblies>True</AotAssemblies>` or in .NET 6 `<RunAOTCompilation>True</RunAOTCompilation>`

Consider submitting a [bug][bug] if you are getting one of these
warnings under normal circumstances.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ They run in a context of an inner build with a single $(RuntimeIdentifier).

<Target Name="_AndroidAot"
Condition=" '$(AotAssemblies)' == 'true' and '$(RuntimeIdentifier)' != '' "
DependsOnTargets="_AndroidAotInputs"
DependsOnTargets="_CreatePropertiesCache;_AndroidAotInputs"
Inputs="@(_AndroidAotInputs)"
Outputs="$(_AndroidStampDirectory)_AndroidAot.stamp">
<ItemGroup>
Expand Down
4 changes: 4 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ The term "lock file" comes from NuGet. For example, search for "UnauthorizedLock
<value>Using fast deployment and a code shrinker at the same time is not recommended. Use fast deployment for Debug configurations and a code shrinker for Release configurations.</value>
<comment>The following are literal names and should not be translated: Debug, Release.</comment>
</data>
<data name="XA0119_Interpreter" xml:space="preserve">
<value>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</value>
<comment>The following are literal names and should not be translated: AOT, Debug, Release.</comment>
</data>
<data name="XA0121" xml:space="preserve">
<value>Assembly '{0}' is using '[assembly: {1}]', which is no longer supported. Use a newer version of this NuGet package or notify the library author.</value>
<comment>The following are literal names and should not be translated: [assembly: {1}], NuGet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ This error is likely caused by an issue with the AndroidManifest.xml file or an
<note>
{0} - The Java SDK version number</note>
</trans-unit>
<trans-unit id="XA0119_Interpreter">
<source>Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</source>
<target state="new">Disabling the interpreter; using the interpreter and AOT at the same time is not supported. Use the interpreter for hot reload support in Debug configurations and AOT for Release configurations.</target>
<note>The following are literal names and should not be translated: AOT, Debug, Release.</note>
</trans-unit>
<trans-unit id="XA0125">
<source>'{0}' is using a deprecated debug information level.
Set the debugging information to Portable in the Visual Studio project property pages or edit the project file in a text editor and set the 'DebugType' MSBuild property to 'portable' to use the newer, cross-platform debug information level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1740,6 +1740,21 @@ public void XA0119AAB ()
}
}

[Test]
public void XA0119Interpreter ()
{
var proj = new XamarinAndroidApplicationProject {
IsRelease = true,
};
proj.SetProperty ("UseInterpreter", "true");
proj.SetProperty ("AotAssemblies", "true");
using (var builder = CreateApkBuilder ()) {
builder.ThrowOnBuildFailure = false;
Assert.IsTrue (builder.Build (proj), "Build should have succeeded.");
Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, "XA0119"), "Output should contain XA0119 warnings");
}
}

[Test]
public void FastDeploymentDoesNotAddContentProvider ()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,37 @@ public void BenchmarkDotNet ()
builder.AssertHasNoWarnings ();
}

static readonly object [] SettingCombinationsSource = new object [] {
// Interpreter + AOT
new object [] {
/* isRelease */ true,
/* useInterpreter */ true,
/* publishTrimmed */ true,
/* aot */ true,
},
// Debug + AOT
new object [] {
/* isRelease */ false,
/* useInterpreter */ false,
/* publishTrimmed */ true,
/* aot */ true,
},
};

[Test]
[TestCaseSource (nameof (SettingCombinationsSource))]
public void SettingCombinations (bool isRelease, bool useInterpreter, bool publishTrimmed, bool aot)
{
var proj = new XASdkProject {
IsRelease = isRelease,
};
proj.SetProperty ("UseInterpreter", useInterpreter.ToString ());
proj.SetProperty ("PublishTrimmed", publishTrimmed.ToString ());
proj.SetProperty ("RunAOTCompilation", aot.ToString ());
var builder = CreateDotNetBuilder (proj);
Assert.IsTrue (builder.Build (), $"{proj.ProjectName} should succeed");
}

DotNetCLI CreateDotNetBuilder (string relativeProjectDir = null)
{
if (string.IsNullOrEmpty (relativeProjectDir)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.

<!-- Ahead-of-time compilation properties -->
<AotAssemblies Condition=" '$(AndroidEnableProfiledAot)' == 'True' ">True</AotAssemblies>
<AndroidAotMode Condition=" '$(AndroidUseInterpreter)' != 'False' ">Interpreter</AndroidAotMode>
<AndroidAotMode Condition=" '$(AotAssemblies)' != 'True' And '$(AndroidUseInterpreter)' == 'True' ">Interpreter</AndroidAotMode>
<AndroidAotMode Condition=" '$(AndroidAotMode)' == '' And '$(AotAssemblies)' == 'True' ">Normal</AndroidAotMode>
<AndroidAotMode Condition=" '$(AndroidAotMode)' == '' ">None</AndroidAotMode>
<AotAssemblies Condition=" '$(AndroidAotMode)' != '' And '$(AndroidAotMode)' != 'None' And '$(AndroidAotMode)' != 'Interpreter' ">True</AotAssemblies>
Expand Down Expand Up @@ -445,6 +445,10 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
ResourceName="XA0119_AAB"
Condition=" '$(EmbedAssembliesIntoApk)' != 'True' And '$(AndroidPackageFormat)' == 'aab' "
/>
<AndroidWarning Code="XA0119"
ResourceName="XA0119_Interpreter"
Condition=" '$(AndroidUseInterpreter)' == 'True' And '$(AotAssemblies)' == 'True' "
/>
<AndroidWarning Code="XA1027"
ResourceName="XA1027"
Condition=" $(_AndroidXA1027) == 'true' "
Expand Down

0 comments on commit 513f613

Please sign in to comment.