Skip to content

Commit ea38c0c

Browse files
authored
[CoreCLR] More CLR hosting support (#9572)
Implements but does not complete CoreCLR host support. The runtime build will be enabled later, which will also be used to fix and update tests, potentially introducing new ones. This is in the interest to keep this PR as small as possible and getting the changes that affect the whole build system into `main` as quickly as possible.
1 parent c429ec0 commit ea38c0c

File tree

69 files changed

+4829
-236
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+4829
-236
lines changed

CLR-Host-Notes.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Notes
2+
3+
## Potential optimizations
4+
5+
* https://github.com/dotnet/runtime/blob/9b24fb60a19f62620ca1fc5e4eb2e3ae0b3b086d/src/coreclr/binder/assemblybindercommon.cpp#L844-L889
6+
* Managed C++ assemblies aren't available on Unix, no point in looking for them
7+
* `candidates[]` is `WCHAR*`, while `ProbeAppBundle` takes UTF-8 - no point in doing the
8+
conversion here
9+
* Host contract
10+
* It might make sense to pass strings as Unicode to host and back, to avoid conversions.
11+
p/invoke names for instance, can be Unicode. So can be the assembly names. Native library
12+
names should be UTF-8, but we can generate lookup tables for those at application build time
13+
(e.g. indexed by an xxHash of the Unicode version of the name) - no conversion at run time.
14+
* We need declarations of all he possible HRESULT errors (`S_OK` etc)
15+
16+
## Stuff that should be changed
17+
18+
### Logging
19+
Currently, most of the messages logged by the runtime end up in `/dev/null` (either because they
20+
are disabled in release build or because they log to stdio which doesn't work on Android).
21+
22+
Logcat is the only way to get information from remote devices, especially via Google Play Console.
23+
24+
We should log to logcat:
25+
26+
+ C++ exception messages
27+
+ abort() messages / fatal errors
28+
+ warnings
29+
+ errors
30+
31+
A subsystem should be added which will provide a single function that will do actual output, implementation of which
32+
will be specific to the platform. API should allow specification of severity, the actual message, and possibly a flag
33+
to indicate whether the process should be aborted (the decision might also be based on the severity). Severity should
34+
be shared between all targets, which then can (if needed) translate it to the target platform's value(s), if any.
35+
36+
### Process termination
37+
Runtime currently calls `abort()` in several places. This should probably become part of the host contract instead.
38+
Being part of the contract, the target platform could implement process termination on `abort()` in a uniform way
39+
(includes platform-specific logging, preparation etc)
40+
41+
## Issues and workarounds
42+

Configuration.props

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,15 @@
220220
<AndroidAbiAndRuntimeFlavor Include="@(AndroidSupportedTargetJitAbi)" AndroidRuntime="NativeAOT" />
221221
<AndroidAbiAndRuntimeFlavor Include="@(AndroidSupportedTargetJitAbi)" AndroidRuntime="CoreCLR" />
222222
</ItemGroup>
223+
224+
<!-- Whenever there's a need to use a locally built CoreCLR, both .NET for Android and the
225+
application(s) must be built with the same runtime. This property should point to the CoreCLR
226+
artifact directory in its repository checkout:
227+
228+
{PATH_TO_DOTNET_RUNTIME_REPO}/artifacts/bin/microsoft.netcore.app.runtime.android-{ARCH}/{CONFIG}
229+
230+
<PropertyGroup>
231+
<CLRLocalRuntimePath></CLRLocalRuntimePath>
232+
</PropertyGroup>
233+
-->
223234
</Project>

Xamarin.Android.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop.Tools.Diagnost
4545
EndProject
4646
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Java.Interop.Tools.Cecil", "external\Java.Interop\src\Java.Interop.Tools.Cecil\Java.Interop.Tools.Cecil.csproj", "{D48EE8D0-0A0A-4493-AEF5-DAF5F8CF86AD}"
4747
EndProject
48-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "native", "src\native\native-mono.csproj", "{53EE4C57-1C03-405A-8243-8DA539546C88}"
48+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "native-mono", "src\native\native-mono.csproj", "{53EE4C57-1C03-405A-8243-8DA539546C88}"
4949
EndProject
5050
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{CAB438D8-B0F5-4AF0-BEBD-9E2ADBD7B483}"
5151
EndProject

build-tools/create-packs/Microsoft.Android.Runtime.proj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ projects that use the Microsoft.Android framework in .NET 6+.
6060
<_AndroidRuntimePackAssets Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libunwind_xamarin.a" />
6161
</ItemGroup>
6262

63-
<ItemGroup Condition=" '$(AndroidRuntime)' == 'CoreCLR' ">
63+
<ItemGroup Condition=" '$(AndroidRuntime)' != 'NativeAOT' ">
6464
<!-- TODO: the Exists() checks must go away once we build CoreCLR host for all the targets -->
6565
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libc.so') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libc.so" />
6666
<_AndroidRuntimePackAssets Condition=" Exists('$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libdl.so') " Include="$(NativeRuntimeOutputRootDir)$(_RuntimeFlavorDirName)\$(AndroidRID)\libdl.so" />

build-tools/installers/create-installers.targets

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@
133133
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)java_runtime_fastdev_net6.jar" ExcludeFromLegacy="true" />
134134
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)java_runtime_net6.dex" ExcludeFromLegacy="true" />
135135
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)java_runtime_fastdev_net6.dex" ExcludeFromLegacy="true" />
136+
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)java_runtime_clr.jar" ExcludeFromLegacy="true" />
137+
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)java_runtime_fastdev_clr.jar" ExcludeFromLegacy="true" />
138+
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)java_runtime_clr.dex" ExcludeFromLegacy="true" />
139+
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)java_runtime_fastdev_clr.dex" ExcludeFromLegacy="true" />
136140
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)manifestmerger.jar" />
137141
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)proguard-android.txt" />
138142
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)protobuf-net.dll" />
@@ -175,18 +179,6 @@
175179
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)K4os.Compression.LZ4.dll" />
176180
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)ELFSharp.dll" />
177181
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)ManifestOverlays\Timing.xml" />
178-
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)libstubs\android-arm64\libc.so" />
179-
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)libstubs\android-arm64\libm.so" />
180-
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)libstubs\android-arm\libc.so" />
181-
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)libstubs\android-arm\libm.so" />
182-
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)libstubs\android-x64\libc.so" />
183-
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)libstubs\android-x64\libm.so" />
184-
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)libstubs\android-x86\libc.so" />
185-
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)libstubs\android-x86\libm.so" />
186-
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)dsostubs\android-arm64\libarchive-dso-stub.so" />
187-
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)dsostubs\android-arm\libarchive-dso-stub.so" />
188-
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)dsostubs\android-x64\libarchive-dso-stub.so" />
189-
<_MSBuildFiles Include="$(MicrosoftAndroidSdkOutDir)dsostubs\android-x86\libarchive-dso-stub.so" />
190182
</ItemGroup>
191183
<ItemGroup>
192184
<_MSBuildTargetsSrcFiles Include="$(MSBuildTargetsSrcDir)\Xamarin.Android.AvailableItems.targets" />

build-tools/scripts/generate-pinvoke-tables.sh

Lines changed: 62 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22
MY_DIR="$(dirname $0)"
33
HOST="$(uname | tr A-Z a-z)"
44

5-
NATIVE_DIR="${MY_DIR}/../../src/native/mono"
6-
MONODROID_SOURCE_DIR="${NATIVE_DIR}/pinvoke-override"
7-
GENERATOR_SOURCE="${MONODROID_SOURCE_DIR}/generate-pinvoke-tables.cc"
8-
GENERATOR_BINARY="${MONODROID_SOURCE_DIR}/generate-pinvoke-tables"
9-
TARGET_FILE="${MONODROID_SOURCE_DIR}/pinvoke-tables.include"
5+
NATIVE_DIR="${MY_DIR}/../../src/native"
6+
MONODROID_SOURCE_DIR="${NATIVE_DIR}/mono/pinvoke-override"
7+
MONODROID_INCLUDE_DIR="${NATIVE_DIR}/mono/shared"
8+
CLR_SOURCE_DIR="${NATIVE_DIR}/clr/host"
9+
CLR_INCLUDE_DIR="${NATIVE_DIR}/clr/include/shared"
10+
GENERATOR_SOURCE="generate-pinvoke-tables.cc"
11+
GENERATOR_BINARY="generate-pinvoke-tables"
12+
TARGET_FILE="pinvoke-tables.include"
1013
GENERATED_FILE="${TARGET_FILE}.generated"
1114
DIFF_FILE="${TARGET_FILE}.diff"
1215
EXTERNAL_DIR="${MY_DIR}/../../external/"
@@ -64,33 +67,61 @@ case ${HOST} in
6467
*) die Unsupported OS ;;
6568
esac
6669

67-
${COMPILER} -O2 -std=c++20 -I${EXTERNAL_DIR} -I${EXTERNAL_DIR}/constexpr-xxh3 -I${NATIVE_DIR}/shared -I${NATIVE_DIR}/../common/include "${GENERATOR_SOURCE}" -o "${GENERATOR_BINARY}"
68-
"${GENERATOR_BINARY}" "${GENERATED_FILE}"
69-
70-
FILES_DIFFER="no"
71-
cmp "${GENERATED_FILE}" "${TARGET_FILE}" > /dev/null 2>&1 || FILES_DIFFER="yes"
72-
73-
RETVAL=0
74-
if [ "${TEST_ONLY}" == "no" ]; then
75-
if [ "${FILES_DIFFER}" == "yes" ]; then
76-
mv "${GENERATED_FILE}" "${TARGET_FILE}"
77-
else
78-
rm "${GENERATED_FILE}"
79-
fi
80-
else
81-
if [ "${FILES_DIFFER}" == "yes" ]; then
82-
echo "Generated p/invokes table file differs from the current one"
83-
diff -U3 -Narp "${TARGET_FILE}" "${GENERATED_FILE}" > "${DIFF_FILE}"
84-
85-
echo "Diff file saved in: ${DIFF_FILE}"
86-
echo "------ DIFF START ------"
87-
cat "${DIFF_FILE}"
88-
echo "------ DIFF END ------"
89-
echo
90-
RETVAL=1
70+
function generate()
71+
{
72+
local SOURCE_DIR="${1}"
73+
local INCLUDE_DIR="${2}"
74+
local SOURCE="${SOURCE_DIR}/${GENERATOR_SOURCE}"
75+
local BINARY="${SOURCE_DIR}/${GENERATOR_BINARY}"
76+
local RESULT="${SOURCE_DIR}/${GENERATED_FILE}"
77+
local TARGET="${SOURCE_DIR}/${TARGET_FILE}"
78+
local DIFF="${SOURCE_DIR}/${DIFF_FILE}"
79+
80+
${COMPILER} -O2 -std=c++20 -I${EXTERNAL_DIR} -I${EXTERNAL_DIR}/constexpr-xxh3 -I${INCLUDE_DIR} -I${NATIVE_DIR}/common/include "${SOURCE}" -o "${BINARY}"
81+
"${BINARY}" "${RESULT}"
82+
83+
FILES_DIFFER="no"
84+
cmp "${RESULT}" "${TARGET}" > /dev/null 2>&1 || FILES_DIFFER="yes"
85+
86+
if [ "${TEST_ONLY}" == "no" ]; then
87+
if [ "${FILES_DIFFER}" == "yes" ]; then
88+
mv "${RESULT}" "${TARGET}"
89+
else
90+
rm "${RESULT}"
91+
fi
9192
else
92-
echo Generated file is identical to the current one
93+
if [ "${FILES_DIFFER}" == "yes" ]; then
94+
echo "Generated p/invokes table file differs from the current one"
95+
diff -U3 -Narp "${TARGET}" "${RESULT}" > "${DIFF}"
96+
97+
echo "Diff file saved in: ${DIFF}"
98+
echo "------ DIFF START ------"
99+
cat "${DIFF}"
100+
echo "------ DIFF END ------"
101+
echo
102+
RETVAL=1
103+
else
104+
echo Generated file is identical to the current one
105+
fi
93106
fi
94-
fi
107+
}
108+
109+
RETVAL=0
110+
cat <<EOF
111+
**
112+
** Generating for MonoVM
113+
**
114+
EOF
115+
generate "${MONODROID_SOURCE_DIR}" "${MONODROID_INCLUDE_DIR}"
116+
117+
cat <<EOF
118+
119+
--------------------------------------
120+
121+
**
122+
** Generating for CoreCLR
123+
**
124+
EOF
125+
generate "${CLR_SOURCE_DIR}" "${CLR_INCLUDE_DIR}"
95126

96127
exit ${RETVAL}

build-tools/scripts/xa_build_configuration.cmake.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,8 @@ set(NETCORE_APP_RUNTIME_DIR_ARM "@NETCORE_APP_RUNTIME_ANDROID_ARM@")
22
set(NETCORE_APP_RUNTIME_DIR_ARM64 "@NETCORE_APP_RUNTIME_ANDROID_ARM64@")
33
set(NETCORE_APP_RUNTIME_DIR_X86 "@NETCORE_APP_RUNTIME_ANDROID_X86@")
44
set(NETCORE_APP_RUNTIME_DIR_X86_64 "@NETCORE_APP_RUNTIME_ANDROID_X86_64@")
5+
6+
set(CORECLR_APP_RUNTIME_DIR_ARM "@CORECLR_APP_RUNTIME_ANDROID_ARM@")
7+
set(CORECLR_APP_RUNTIME_DIR_ARM64 "@CORECLR_APP_RUNTIME_ANDROID_ARM64@")
8+
set(CORECLR_APP_RUNTIME_DIR_X86 "@CORECLR_APP_RUNTIME_ANDROID_X86@")
9+
set(CORECLR_APP_RUNTIME_DIR_X86_64 "@CORECLR_APP_RUNTIME_ANDROID_X86_64@")

build-tools/xaprepare/xaprepare/ConfigAndData/Configurables.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,18 @@ public static partial class Paths
191191
public static string OpenJDKInstallDir => GetCachedPath (ref openJDKInstallDir, () => Path.Combine (ctx.Properties.GetRequiredValue (KnownProperties.AndroidToolchainDirectory), Defaults.JdkFolder));
192192
public static string OpenJDKCacheDir => GetCachedPath (ref openJDKCacheDir, () => ctx.Properties.GetRequiredValue (KnownProperties.AndroidToolchainCacheDirectory));
193193

194-
// .NET 6
194+
// .NET 6+
195195
public static string NetcoreAppRuntimeAndroidARM => GetCachedPath (ref netcoreAppRuntimeAndroidARM, () => GetNetcoreAppRuntimePath (ctx, "arm"));
196196
public static string NetcoreAppRuntimeAndroidARM64 => GetCachedPath (ref netcoreAppRuntimeAndroidARM64, () => GetNetcoreAppRuntimePath (ctx, "arm64"));
197197
public static string NetcoreAppRuntimeAndroidX86 => GetCachedPath (ref netcoreAppRuntimeAndroidX86, () => GetNetcoreAppRuntimePath (ctx, "x86"));
198198
public static string NetcoreAppRuntimeAndroidX86_64 => GetCachedPath (ref netcoreAppRuntimeAndroidX86_64, () => GetNetcoreAppRuntimePath (ctx, "x64"));
199199

200+
// CoreCLR
201+
public static string CoreClrAppRuntimeAndroidARM => GetCachedPath (ref coreclrAppRuntimeAndroidARM, () => GetCoreClrAppRuntimePath (ctx, "arm"));
202+
public static string CoreClrAppRuntimeAndroidARM64 => GetCachedPath (ref coreclrAppRuntimeAndroidARM64, () => GetCoreClrAppRuntimePath (ctx, "arm64"));
203+
public static string CoreClrAppRuntimeAndroidX86 => GetCachedPath (ref coreclrAppRuntimeAndroidX86, () => GetCoreClrAppRuntimePath (ctx, "x86"));
204+
public static string CoreClrAppRuntimeAndroidX86_64 => GetCachedPath (ref coreclrAppRuntimeAndroidX86_64, () => GetCoreClrAppRuntimePath (ctx, "x64"));
205+
200206
public static string MicrosoftNETWorkloadMonoPackageDir => Path.Combine (
201207
XAPackagesDir,
202208
$"microsoft.net.workload.mono.toolchain.{{0}}.manifest-{ctx.Properties.GetRequiredValue (KnownProperties.DotNetMonoManifestVersionBand)}",
@@ -242,6 +248,17 @@ static string GetNetcoreAppRuntimePath (Context ctx, string androidTarget)
242248
);
243249
}
244250

251+
static string GetCoreClrAppRuntimePath (Context ctx, string androidTarget)
252+
{
253+
return Path.Combine (
254+
XAPackagesDir,
255+
$"microsoft.netcore.app.runtime.android-{androidTarget}",
256+
ctx.Properties.GetRequiredValue (KnownProperties.MicrosoftNETCoreAppRefPackageVersion),
257+
"runtimes",
258+
$"android-{androidTarget}"
259+
);
260+
}
261+
245262
static string EnsureAndroidToolchainBinDirectories ()
246263
{
247264
if (androidToolchainBinDirectory != null)
@@ -278,6 +295,10 @@ static string GetCachedPath (ref string? variable, Func<string> creator)
278295
static string? netcoreAppRuntimeAndroidARM64;
279296
static string? netcoreAppRuntimeAndroidX86;
280297
static string? netcoreAppRuntimeAndroidX86_64;
298+
static string? coreclrAppRuntimeAndroidARM;
299+
static string? coreclrAppRuntimeAndroidARM64;
300+
static string? coreclrAppRuntimeAndroidX86;
301+
static string? coreclrAppRuntimeAndroidX86_64;
281302
}
282303
}
283304
}

build-tools/xaprepare/xaprepare/Steps/Step_GenerateFiles.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ GeneratedFile Get_Cmake_XA_Build_Configuration (Context context)
9898
{ "@NETCORE_APP_RUNTIME_ANDROID_ARM64@", Utilities.EscapePathSeparators (Configurables.Paths.NetcoreAppRuntimeAndroidARM64) },
9999
{ "@NETCORE_APP_RUNTIME_ANDROID_X86@", Utilities.EscapePathSeparators (Configurables.Paths.NetcoreAppRuntimeAndroidX86) },
100100
{ "@NETCORE_APP_RUNTIME_ANDROID_X86_64@", Utilities.EscapePathSeparators (Configurables.Paths.NetcoreAppRuntimeAndroidX86_64) },
101+
102+
{ "@CORECLR_APP_RUNTIME_ANDROID_ARM@", Utilities.EscapePathSeparators (Configurables.Paths.CoreClrAppRuntimeAndroidARM) },
103+
{ "@CORECLR_APP_RUNTIME_ANDROID_ARM64@", Utilities.EscapePathSeparators (Configurables.Paths.CoreClrAppRuntimeAndroidARM64) },
104+
{ "@CORECLR_APP_RUNTIME_ANDROID_X86@", Utilities.EscapePathSeparators (Configurables.Paths.CoreClrAppRuntimeAndroidX86) },
105+
{ "@CORECLR_APP_RUNTIME_ANDROID_X86_64@", Utilities.EscapePathSeparators (Configurables.Paths.CoreClrAppRuntimeAndroidX86_64) },
101106
};
102107

103108
return new GeneratedPlaceholdersFile (
@@ -107,7 +112,7 @@ GeneratedFile Get_Cmake_XA_Build_Configuration (Context context)
107112
);
108113
}
109114

110-
GeneratedFile Get_Cmake_Presets (Context context)
115+
GeneratedFile GetCmakePresetsCommon (Context context, string sourcesDir)
111116
{
112117
const string OutputFileName = "CMakePresets.json";
113118

@@ -126,11 +131,16 @@ GeneratedFile Get_Cmake_Presets (Context context)
126131

127132
return new GeneratedPlaceholdersFile (
128133
replacements,
129-
Path.Combine (Configurables.Paths.NativeSourcesDir, $"{OutputFileName}.in"),
130-
Path.Combine (Configurables.Paths.NativeSourcesDir, OutputFileName)
134+
Path.Combine (sourcesDir, $"{OutputFileName}.in"),
135+
Path.Combine (sourcesDir, OutputFileName)
131136
);
132137
}
133138

139+
GeneratedFile Get_Cmake_Presets (Context context)
140+
{
141+
return GetCmakePresetsCommon (context, Configurables.Paths.NativeSourcesDir);
142+
}
143+
134144
GeneratedFile Get_Configuration_Generated_Props (Context context)
135145
{
136146
const string OutputFileName = "Configuration.Generated.props";

build-tools/xaprepare/xaprepare/package-download.proj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Otherwise, $(MicrosoftNETCoreAppRefPackageVersion) from eng/Versions.props will
2020
<PackageDownload Include="Microsoft.NETCore.App.Runtime.Mono.android-arm64" Version="[$(DotNetRuntimePacksVersion)]" />
2121
<PackageDownload Include="Microsoft.NETCore.App.Runtime.Mono.android-x86" Version="[$(DotNetRuntimePacksVersion)]" />
2222
<PackageDownload Include="Microsoft.NETCore.App.Runtime.Mono.android-x64" Version="[$(DotNetRuntimePacksVersion)]" />
23+
<PackageDownload Include="Microsoft.NETCore.App.Runtime.android-arm64" Version="[$(DotNetRuntimePacksVersion)]" />
24+
<PackageDownload Include="Microsoft.NETCore.App.Runtime.android-x64" Version="[$(DotNetRuntimePacksVersion)]" />
2325
<PackageDownload Include="Microsoft.NET.Workload.Mono.ToolChain.Current.Manifest-$(DotNetMonoManifestVersionBand)" Version="[$(DotNetRuntimePacksVersion)]" />
2426
<PackageDownload Include="Microsoft.NET.Workload.Mono.ToolChain.net6.Manifest-$(DotNetMonoManifestVersionBand)" Version="[$(DotNetRuntimePacksVersion)]" />
2527
<PackageDownload Include="Microsoft.NET.Workload.Mono.ToolChain.net7.Manifest-$(DotNetMonoManifestVersionBand)" Version="[$(DotNetRuntimePacksVersion)]" />

0 commit comments

Comments
 (0)