Skip to content

Commit b2c73ff

Browse files
[NativeAOT] support multi-RID builds (#9826)
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); // … }
1 parent 2c28801 commit b2c73ff

File tree

5 files changed

+35
-16
lines changed

5 files changed

+35
-16
lines changed

samples/NativeAOT/NativeAOT.csproj

-4
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,12 @@
99
<ApplicationVersion>1</ApplicationVersion>
1010
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
1111
<AndroidPackageFormat>apk</AndroidPackageFormat>
12-
<!-- Default to arm64 device -->
13-
<RuntimeIdentifier>android-arm64</RuntimeIdentifier>
1412
<!-- Only property required to opt into NativeAOT -->
1513
<PublishAot>true</PublishAot>
1614
</PropertyGroup>
1715

1816
<!-- Settings for CI -->
1917
<PropertyGroup Condition=" '$(RunningOnCI)' == 'true' ">
20-
<!-- x86_64 emulator -->
21-
<RuntimeIdentifier>android-x64</RuntimeIdentifier>
2218
<_NuGetFolderOnCI>..\..\bin\Build$(Configuration)\nuget-unsigned</_NuGetFolderOnCI>
2319
<RestoreAdditionalProjectSources Condition="Exists('$(_NuGetFolderOnCI)')">$(_NuGetFolderOnCI)</RestoreAdditionalProjectSources>
2420
<_FastDeploymentDiagnosticLogging>true</_FastDeploymentDiagnosticLogging>

src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ This file contains the NativeAOT-specific MSBuild logic for .NET for Android.
1313
<PropertyGroup>
1414
<_AndroidRuntimePackRuntime>NativeAOT</_AndroidRuntimePackRuntime>
1515
<AndroidCodegenTarget Condition=" '$(AndroidCodegenTarget)' == '' ">JavaInterop1</AndroidCodegenTarget>
16+
<!-- .NET SDK gives: error NETSDK1191: A runtime identifier for the property 'PublishAot' couldn't be inferred. Specify a rid explicitly. -->
17+
<AllowPublishAotWithoutRuntimeIdentifier Condition=" '$(AllowPublishAotWithoutRuntimeIdentifier)' == '' ">true</AllowPublishAotWithoutRuntimeIdentifier>
1618
<!-- NativeAOT's targets currently gives an error about cross-compilation -->
1719
<DisableUnsupportedError Condition=" $([MSBuild]::IsOSPlatform('windows')) and '$(DisableUnsupportedError)' == '' ">true</DisableUnsupportedError>
1820
</PropertyGroup>

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs

+8-12
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,8 @@ public void NativeAOT ()
125125
{
126126
var proj = new XamarinAndroidApplicationProject {
127127
ProjectName = "Hello",
128-
IsRelease = true,
129-
RuntimeIdentifier = "android-arm64",
130-
// Add locally downloaded NativeAOT packs
131-
ExtraNuGetConfigSources = {
132-
Path.Combine (XABuildPaths.BuildOutputDirectory, "nuget-unsigned"),
133-
}
134128
};
135-
proj.SetProperty ("PublishAot", "true");
136-
proj.SetProperty ("AndroidNdkDirectory", AndroidNdkPath);
129+
proj.SetPublishAot (true, AndroidNdkPath);
137130
proj.SetProperty ("_ExtraTrimmerArgs", "--verbose");
138131

139132
// Required for java/util/ArrayList assertion below
@@ -149,16 +142,19 @@ public void NativeAOT ()
149142
];
150143
string[] mono_files = [
151144
"lib/arm64-v8a/libmonosgen-2.0.so",
145+
"lib/x86_64/libmonosgen-2.0.so",
152146
];
153147
string [] nativeaot_files = [
154148
$"lib/arm64-v8a/lib{proj.ProjectName}.so",
155149
"lib/arm64-v8a/libc++_shared.so",
150+
$"lib/x86_64/lib{proj.ProjectName}.so",
151+
"lib/x86_64/libc++_shared.so",
156152
];
157153

158-
var intermediate = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, proj.RuntimeIdentifier);
159-
var output = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, proj.RuntimeIdentifier);
154+
var intermediate = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath);
155+
var output = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath);
160156

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

172168
var typemap = new Dictionary<string, TypeReference> ();
173-
var linkedRuntimeAssembly = Path.Combine (intermediate, "linked", "Microsoft.Android.Runtime.NativeAOT.dll");
169+
var linkedRuntimeAssembly = Path.Combine (intermediate, "android-arm64", "linked", "Microsoft.Android.Runtime.NativeAOT.dll");
174170
FileAssert.Exists (linkedRuntimeAssembly);
175171
using (var assembly = AssemblyDefinition.ReadAssembly (linkedRuntimeAssembly)) {
176172
var type = assembly.MainModule.Types.FirstOrDefault (t => t.Name == "NativeAotTypeManager");

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/KnownProperties.cs

+1
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,6 @@ public static class KnownProperties
3636
public const string _AndroidAllowDeltaInstall = "_AndroidAllowDeltaInstall";
3737
public const string Nullable = "Nullable";
3838
public const string ImplicitUsings = "ImplicitUsings";
39+
public const string PublishAot = "PublishAot";
3940
}
4041
}

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Android/XamarinAndroidApplicationProject.cs

+24
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,30 @@ public bool EnableMarshalMethods {
165165
set { SetProperty (KnownProperties.AndroidEnableMarshalMethods, value.ToString ()); }
166166
}
167167

168+
private bool PublishAot {
169+
get { return string.Equals (GetProperty (KnownProperties.PublishAot), "True", StringComparison.OrdinalIgnoreCase); }
170+
set { SetProperty (KnownProperties.PublishAot, value.ToString ()); }
171+
}
172+
173+
/// <summary>
174+
/// Sets properties required for $(PublishAot)=true
175+
/// </summary>
176+
public void SetPublishAot (bool value, string androidNdkPath)
177+
{
178+
IsRelease = value;
179+
PublishAot = value;
180+
SetProperty ("AndroidNdkDirectory", androidNdkPath);
181+
182+
// NuGet feed needed as Microsoft.Android.Runtime.NativeAOT packs not installed in workload by default
183+
var source = Path.Combine (XABuildPaths.BuildOutputDirectory, "nuget-unsigned");
184+
if (value) {
185+
if (!ExtraNuGetConfigSources.Contains (source))
186+
ExtraNuGetConfigSources.Add (source);
187+
} else {
188+
ExtraNuGetConfigSources.Remove (source);
189+
}
190+
}
191+
168192
public string AndroidManifest { get; set; }
169193
public string LayoutMain { get; set; }
170194
public string MainActivity { get; set; }

0 commit comments

Comments
 (0)