From 546c24189cc3344fa02b70306af311fed0405c09 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 10 Dec 2024 09:00:42 -0600 Subject: [PATCH] [NativeAOT] MSBuild-related logic to get projects to build This is an initial step to get the NativeAOT build working the same as iOS does. At a high level, the changes are: * Run `ILLink` with our existing trimmer/linker pipeline. * Temporarily change our RID to `linux-bionic-arm64`. * Pass the output to `ILC`, the NativeAOT compiler. * Turn the RID back to `android-arm64`. A list of MSBuild/workload changes required so far: * `$(UseMonoRuntime)` is false when `$(PublishAot)` is true * Set `$(_IsPublishing)` as NativeAOT expects `dotnet publish` to be the only way NativeAOT is used. Setting this in our targets allows the proper `*.NativeAOT.*` packs to restore inside of a `dotnet build`. * `$(SelfContained)=true`, seems to be required for the `linux-bionic-arm64` runtime packs to restore. All Android apps are self-contained, so this might be fine. * Create a new `Microsoft.Android.Sdk.NativeAOT.targets` file that uses `$(_AndroidNdkDirectory)` to set various properties for NativeAOT's build (ILC). * `HACK:` set `$(_targetOS)` to `linux` to make the NativeAOT build attempt to run. `--targetos:android` results in a build error that says Android is not supported. * Disable `$(RunAOTCompilation)`, Mono's AOT compiler and the `` MSBuild task. * Disable `$(AndroidEnableMarshalMethods)` to be re-enabled in a future PR. A list of blockers or things that don't work yet: * NativeAOT apps won't launch yet (future changes for that) * The NativeAOT cross compiler doesn't run on Windows: Microsoft.NETCore.Native.Publish.targets(61,5): Cross-OS native compilation is not supported. Microsoft.NETCore.Native.Unix.targets(296,5): error : Platform linker ('C:\Android\android-sdk\ndk\26.3.11579264\toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android21-clang++' or 'gcc') not found in PATH. Ensure you have all the required prerequisites documented at https://aka.ms/nativeaot-prerequisites. * You can only target `-r android-arm64` as there are no other `linux-bionic-*` runtime packs yet. * `-p:PublishAotUsingRuntimePack=true` is currently required, but I will investigate if we should just set this by default. --- ...soft.Android.Sdk.DefaultProperties.targets | 8 +- .../Microsoft.Android.Sdk.NativeAOT.targets | 79 +++++++++++++++++++ .../targets/Microsoft.Android.Sdk.targets | 1 + .../Xamarin.Android.Build.Tests/BuildTest2.cs | 24 ++++++ .../Xamarin.Android.Common.targets | 6 +- 5 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets index f4b2c338709..d10521b1b97 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets @@ -13,6 +13,7 @@ false $(AndroidGenerateResourceDesigner) true + true false false false @@ -23,7 +24,10 @@ See: https://github.com/dotnet/sdk/blob/955c0fc7b06e2fa34bacd076ed39f61e4fb61716/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Publish.targets#L16 --> <_GetChildProjectCopyToPublishDirectoryItems>false + false true + + <_IsPublishing Condition=" '$(_IsPublishing)' == '' and '$(PublishAot)' == 'true' ">true $(AndroidMinimumSupportedApiLevel) @@ -89,8 +93,8 @@ android-arm64;android-x64 true - - true + + true true false <_AndroidXA1029 Condition=" '$(AotAssemblies)' != '' ">true diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets new file mode 100644 index 00000000000..78cb1632cea --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets @@ -0,0 +1,79 @@ + + + + + + + _AndroidBeforeIlcCompile; + SetupOSSpecificProps; + PrepareForILLink; + ILLink; + ComputeIlcCompileInputs; + _AndroidComputeIlcCompileInputs; + $(IlcCompileDependsOn) + + + + + + + <_NdkSysrootAbi>aarch64-linux-android + <_NdkClangPrefix>aarch64-linux-android21- + <_NdkPrebuiltAbi Condition=" $([MSBuild]::IsOSPlatform('windows')) ">windows-x86_64 + <_NdkPrebuiltAbi Condition=" $([MSBuild]::IsOSPlatform('osx')) ">darwin-x86_64 + <_NdkPrebuiltAbi Condition=" $([MSBuild]::IsOSPlatform('linux')) ">linux-x86_64 + <_NdkSysrootDir>$(_AndroidNdkDirectory)toolchains/llvm/prebuilt/$(_NdkPrebuiltAbi)/sysroot/usr/lib/$(_NdkSysrootAbi) + <_NdkBinDir>$(_AndroidNdkDirectory)toolchains/llvm/prebuilt/$(_NdkPrebuiltAbi)/bin/ + $(_NdkBinDir)$(_NdkClangPrefix)clang++ + $(CppCompilerAndLinker) + $(_NdkBinDir)llvm-objcopy + + + true + + <_OriginalSuppressTrimAnalysisWarnings>$(SuppressTrimAnalysisWarnings) + true + + + + <_OriginalRuntimeIdentifier>$(RuntimeIdentifier) + linux-bionic-arm64 + + <_targetOS>linux + + <_linuxLibcFlavor>bionic + + + + + + + $(_OriginalSuppressTrimAnalysisWarnings) + + + + + + + + + + + + + + + $(_OriginalRuntimeIdentifier) + + + + diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.targets index f914dba459a..16610e6db82 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.targets +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.targets @@ -27,5 +27,6 @@ + diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs index 01779040604..638b983affc 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs @@ -105,6 +105,30 @@ public void BuildBasicApplication ([Values (true, false)] bool isRelease, [Value } } + [Test] + public void NativeAOT () + { + if (IsWindows) { + // Microsoft.NETCore.Native.Publish.targets(61,5): Cross-OS native compilation is not supported. + // Set $(DisableUnsupportedError)=true, Microsoft.NETCore.Native.Unix.targets(296,5): error : Platform linker ('C:\Android\android-sdk\ndk\26.3.11579264\toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android21-clang++' or 'gcc') not found in PATH. Ensure you have all the required prerequisites documented at https://aka.ms/nativeaot-prerequisites. + Assert.Ignore ("This test is not valid on Windows."); + } + + var proj = new XamarinAndroidApplicationProject { + IsRelease = true, + // Add locally downloaded NativeAOT packs + ExtraNuGetConfigSources = { + Path.Combine (XABuildPaths.BuildOutputDirectory, "nuget-unsigned"), + } + }; + proj.SetRuntimeIdentifier ("arm64-v8a"); + proj.SetProperty ("PublishAot", "true"); + proj.SetProperty ("PublishAotUsingRuntimePack", "true"); + + using var b = CreateApkBuilder (); + Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + } + [Test] public void BuildBasicApplicationThenMoveIt ([Values (true, false)] bool isRelease) { diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 74b3b78a750..0e79b8a3942 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -324,7 +324,9 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. true True False - True + True + + False <_AndroidUseMarshalMethods Condition=" '$(AndroidIncludeDebugSymbols)' == 'True' ">False <_AndroidUseMarshalMethods Condition=" '$(AndroidIncludeDebugSymbols)' != 'True' ">$(AndroidEnableMarshalMethods) @@ -1937,7 +1939,7 @@ because xbuild doesn't support framework reference assemblies.