Skip to content

Commit

Permalink
[NativeAOT] support multi-RID builds (#9826)
Browse files Browse the repository at this point in the history
Context: https://github.com/dotnet/sdk/blob/68bf4cbabc023e5c2752ee4d5ce7e4a40929e748/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets#L227-L229

The only blocker for supporting multi-targeted
`$(RuntimeIdentifiers)=android-arm64;android-x64` builds is the
error message:

	error NETSDK1191: A runtime identifier for the property 'PublishAot' couldn't be inferred. Specify a rid explicitly.

We can set `$(AllowPublishAotWithoutRuntimeIdentifier)` by default,
as this is not an error we'd ever want to show on Android.

After this change I can see the MSBuild terminal logger shows the two
RIDs building in parallel:

	NativeAOT     IlcCompile (8.7s)
	NativeAOT     IlcCompile (8.6s)

And the resulting `.apk` has both `lib/arm64-v8a` and `lib/x86_64`.

I also updated some of our MSBuild test infrastructure to make it
easier to parameterize more MSBuild tests for `$(PublishAot)=true` in
the future.

We'll likely want to update tests like:

	[Test]
	public void SomeTest ([Values (true, false)] bool publishAot)
	{
	    var proj = new XamarinAndroidApplicationProject ();
	    proj.SetPublishAot (publishAot, AndroidNdkPath);
	    // …
	}
  • Loading branch information
jonathanpeppers authored Feb 24, 2025
1 parent 2c28801 commit b2c73ff
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 16 deletions.
4 changes: 0 additions & 4 deletions samples/NativeAOT/NativeAOT.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,12 @@
<ApplicationVersion>1</ApplicationVersion>
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<AndroidPackageFormat>apk</AndroidPackageFormat>
<!-- Default to arm64 device -->
<RuntimeIdentifier>android-arm64</RuntimeIdentifier>
<!-- Only property required to opt into NativeAOT -->
<PublishAot>true</PublishAot>
</PropertyGroup>

<!-- Settings for CI -->
<PropertyGroup Condition=" '$(RunningOnCI)' == 'true' ">
<!-- x86_64 emulator -->
<RuntimeIdentifier>android-x64</RuntimeIdentifier>
<_NuGetFolderOnCI>..\..\bin\Build$(Configuration)\nuget-unsigned</_NuGetFolderOnCI>
<RestoreAdditionalProjectSources Condition="Exists('$(_NuGetFolderOnCI)')">$(_NuGetFolderOnCI)</RestoreAdditionalProjectSources>
<_FastDeploymentDiagnosticLogging>true</_FastDeploymentDiagnosticLogging>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ This file contains the NativeAOT-specific MSBuild logic for .NET for Android.
<PropertyGroup>
<_AndroidRuntimePackRuntime>NativeAOT</_AndroidRuntimePackRuntime>
<AndroidCodegenTarget Condition=" '$(AndroidCodegenTarget)' == '' ">JavaInterop1</AndroidCodegenTarget>
<!-- .NET SDK gives: error NETSDK1191: A runtime identifier for the property 'PublishAot' couldn't be inferred. Specify a rid explicitly. -->
<AllowPublishAotWithoutRuntimeIdentifier Condition=" '$(AllowPublishAotWithoutRuntimeIdentifier)' == '' ">true</AllowPublishAotWithoutRuntimeIdentifier>
<!-- NativeAOT's targets currently gives an error about cross-compilation -->
<DisableUnsupportedError Condition=" $([MSBuild]::IsOSPlatform('windows')) and '$(DisableUnsupportedError)' == '' ">true</DisableUnsupportedError>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,8 @@ public void NativeAOT ()
{
var proj = new XamarinAndroidApplicationProject {
ProjectName = "Hello",
IsRelease = true,
RuntimeIdentifier = "android-arm64",
// Add locally downloaded NativeAOT packs
ExtraNuGetConfigSources = {
Path.Combine (XABuildPaths.BuildOutputDirectory, "nuget-unsigned"),
}
};
proj.SetProperty ("PublishAot", "true");
proj.SetProperty ("AndroidNdkDirectory", AndroidNdkPath);
proj.SetPublishAot (true, AndroidNdkPath);
proj.SetProperty ("_ExtraTrimmerArgs", "--verbose");

// Required for java/util/ArrayList assertion below
Expand All @@ -149,16 +142,19 @@ public void NativeAOT ()
];
string[] mono_files = [
"lib/arm64-v8a/libmonosgen-2.0.so",
"lib/x86_64/libmonosgen-2.0.so",
];
string [] nativeaot_files = [
$"lib/arm64-v8a/lib{proj.ProjectName}.so",
"lib/arm64-v8a/libc++_shared.so",
$"lib/x86_64/lib{proj.ProjectName}.so",
"lib/x86_64/libc++_shared.so",
];

var intermediate = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, proj.RuntimeIdentifier);
var output = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, proj.RuntimeIdentifier);
var intermediate = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath);
var output = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath);

var linkedMonoAndroidAssembly = Path.Combine (intermediate, "linked", "Mono.Android.dll");
var linkedMonoAndroidAssembly = Path.Combine (intermediate, "android-arm64", "linked", "Mono.Android.dll");
FileAssert.Exists (linkedMonoAndroidAssembly);
using (var assembly = AssemblyDefinition.ReadAssembly (linkedMonoAndroidAssembly)) {
var typeName = "Android.App.Activity";
Expand All @@ -170,7 +166,7 @@ public void NativeAOT ()
}

var typemap = new Dictionary<string, TypeReference> ();
var linkedRuntimeAssembly = Path.Combine (intermediate, "linked", "Microsoft.Android.Runtime.NativeAOT.dll");
var linkedRuntimeAssembly = Path.Combine (intermediate, "android-arm64", "linked", "Microsoft.Android.Runtime.NativeAOT.dll");
FileAssert.Exists (linkedRuntimeAssembly);
using (var assembly = AssemblyDefinition.ReadAssembly (linkedRuntimeAssembly)) {
var type = assembly.MainModule.Types.FirstOrDefault (t => t.Name == "NativeAotTypeManager");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ public static class KnownProperties
public const string _AndroidAllowDeltaInstall = "_AndroidAllowDeltaInstall";
public const string Nullable = "Nullable";
public const string ImplicitUsings = "ImplicitUsings";
public const string PublishAot = "PublishAot";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,30 @@ public bool EnableMarshalMethods {
set { SetProperty (KnownProperties.AndroidEnableMarshalMethods, value.ToString ()); }
}

private bool PublishAot {
get { return string.Equals (GetProperty (KnownProperties.PublishAot), "True", StringComparison.OrdinalIgnoreCase); }
set { SetProperty (KnownProperties.PublishAot, value.ToString ()); }
}

/// <summary>
/// Sets properties required for $(PublishAot)=true
/// </summary>
public void SetPublishAot (bool value, string androidNdkPath)
{
IsRelease = value;
PublishAot = value;
SetProperty ("AndroidNdkDirectory", androidNdkPath);

// NuGet feed needed as Microsoft.Android.Runtime.NativeAOT packs not installed in workload by default
var source = Path.Combine (XABuildPaths.BuildOutputDirectory, "nuget-unsigned");
if (value) {
if (!ExtraNuGetConfigSources.Contains (source))
ExtraNuGetConfigSources.Add (source);
} else {
ExtraNuGetConfigSources.Remove (source);
}
}

public string AndroidManifest { get; set; }
public string LayoutMain { get; set; }
public string MainActivity { get; set; }
Expand Down

0 comments on commit b2c73ff

Please sign in to comment.