-
Notifications
You must be signed in to change notification settings - Fork 561
[coreclr] Initial support of R2R builds #10007
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9a3e300
772de8e
de98b73
619186b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -107,11 +107,8 @@ public void BuildBasicApplication ([Values (true, false)] bool isRelease, [Value | |||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| [Test] | ||||||||||||||||||||||
| public void BasicApplicationOtherRuntime ([Values (true, false)] bool isRelease) | ||||||||||||||||||||||
| public void BasicApplicationBuildCoreCLR ([Values (true, false)] bool isRelease) | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| // This test would fail, as it requires **our** updated runtime pack, which isn't currently created | ||||||||||||||||||||||
| // It is created in `src/native/native-clr.csproj` which isn't built atm. | ||||||||||||||||||||||
| Assert.Ignore ("CoreCLR support isn't fully enabled yet. This test will be enabled in a follow-up PR."); | ||||||||||||||||||||||
| var proj = new XamarinAndroidApplicationProject { | ||||||||||||||||||||||
| IsRelease = isRelease, | ||||||||||||||||||||||
| // Add locally downloaded CoreCLR packs | ||||||||||||||||||||||
|
|
@@ -124,6 +121,64 @@ public void BasicApplicationOtherRuntime ([Values (true, false)] bool isRelease) | |||||||||||||||||||||
| Assert.IsTrue (b.Build (proj), "Build should have succeeded."); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| static object [] ReadyToRunConfigurationSource = new object [] { | ||||||||||||||||||||||
| new object[] { | ||||||||||||||||||||||
| /* isComposite */ true, | ||||||||||||||||||||||
| /* rid */ "android-x64" | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| new object[] { | ||||||||||||||||||||||
| /* isComposite */ false, | ||||||||||||||||||||||
| /* rid */ "android-x64" | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| new object[] { | ||||||||||||||||||||||
| /* isComposite */ true, | ||||||||||||||||||||||
| /* rid */ "android-arm64" | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| new object[] { | ||||||||||||||||||||||
| /* isComposite */ false, | ||||||||||||||||||||||
| /* rid */ "android-arm64" | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| [Test] | ||||||||||||||||||||||
| [TestCaseSource (nameof (ReadyToRunConfigurationSource))] | ||||||||||||||||||||||
| public void BasicApplicationPublishReadyToRun (bool isComposite, string rid) | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| var proj = new XamarinAndroidApplicationProject { | ||||||||||||||||||||||
| IsRelease = true, | ||||||||||||||||||||||
| // Add locally downloaded CoreCLR packs | ||||||||||||||||||||||
| ExtraNuGetConfigSources = { | ||||||||||||||||||||||
| Path.Combine (XABuildPaths.BuildOutputDirectory, "nuget-unsigned"), | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| proj.SetProperty ("RuntimeIdentifier", rid); | ||||||||||||||||||||||
| proj.SetProperty ("UseMonoRuntime", "false"); // Enables CoreCLR | ||||||||||||||||||||||
| proj.SetProperty ("_IsPublishing", "true"); // Make "dotnet build" act as "dotnet publish" | ||||||||||||||||||||||
| proj.SetProperty ("PublishReadyToRun", "true"); // Enable R2R | ||||||||||||||||||||||
| proj.SetProperty ("AndroidEnableAssemblyCompression", "false"); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (isComposite) | ||||||||||||||||||||||
| proj.SetProperty ("PublishReadyToRunComposite", "true"); // Enable R2R composite | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| var b = CreateApkBuilder (); | ||||||||||||||||||||||
| Assert.IsTrue (b.Build (proj), "Build should have succeeded."); | ||||||||||||||||||||||
|
Comment on lines
+164
to
+165
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this test, is there a way to assert the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could maybe just inspect whether assemblies from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be enough to compare the MVID of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inspecting the If not, we could potentially add a custom MSBuild target to the test project that simply prints out There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the test, I think you could use: android/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/LinkerTests.cs Lines 281 to 290 in b54ec05
Then |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| var assemblyName = proj.ProjectName; | ||||||||||||||||||||||
| var apk = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, rid, $"{proj.PackageName}-Signed.apk"); | ||||||||||||||||||||||
| FileAssert.Exists (apk); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| var helper = new ArchiveAssemblyHelper (apk, true); | ||||||||||||||||||||||
| var abi = MonoAndroidHelper.RidToAbi (rid); | ||||||||||||||||||||||
| Assert.IsTrue (helper.Exists ($"assemblies/{abi}/{assemblyName}.dll"), $"{assemblyName}.dll should exist in apk!"); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| using var stream = helper.ReadEntry ($"assemblies/{assemblyName}.dll"); | ||||||||||||||||||||||
| stream.Position = 0; | ||||||||||||||||||||||
| using var peReader = new System.Reflection.PortableExecutable.PEReader (stream); | ||||||||||||||||||||||
| Assert.IsTrue (peReader.PEHeaders.CorHeader.ManagedNativeHeaderDirectory.Size > 0, | ||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jonathanpeppers I used the recommendation from: dotnet/runtime#38440 (comment) to verify that the app main assembly that gets packed into the .apk has R2R image in it. |
||||||||||||||||||||||
| $"ReadyToRun image not found in {assemblyName}.dll! ManagedNativeHeaderDirectory should not be empty!"); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| [Test] | ||||||||||||||||||||||
| public void NativeAOT () | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you update this line for when
$(PublishReadyToRun)is true:android/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.DefaultProperties.targets
Line 34 in 747041d
I would expect
dotnet build -c Release -p:PublishReadyToRun=trueto work by default on Android.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could make this as a temporary workaround for R2R as well.
However, on the long run we shouldn't force
dotnet build -c Release -p:PublishReadyToRun=trueto do publishing as that would not match the behavior on other platforms.On desktop and on iOS, triggering NativeAOT builds only happens with
dotnet publish,dotnet builduses "regular" default runtimes/builds -> CoreCLR desktop, Mono iOSThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for reference, MAUI on Windows uses
PublishReadyToRun=trueby default onReleasebuilds since .NET 7:If R2R is what makes the startup performance reasonable, I think we have to use it by default on Android as well? So,
dotnet build -c Releaseon Android would use R2R?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That only applies if you are publishing your app through Visual Studio, or manually through
dotnet publish.dotnet buildwill not / should not run publish targets whenPublishReadyToRun=true.On a regular console app if you add
PublishReadyToRun=trueto the project and rundotnet buildit will not run R2R AOT compiler. But if you rundotnet publishit will.So to come back to my previous comment, we should not force
_IsPublishing=truefor NativeAOT nor R2R just so we would makedotnet build -p:PublishAOT=trueordotnet build -p:PublishReadyToRun=trueto run/act likedotnet publish, it is against the behavior we have on other platforms (e.g., on macios we solved it with yet another property: https://github.com/dotnet/macios/blob/7cef45367161ca26d3a68e2e096639194ed4df1f/dotnet/targets/Xamarin.Shared.Sdk.props#L39)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The difference is people can actually ship their app with
dotnet build -c Releasefor Android today (and they are). There is currently no requirement to usedotnet publishon Android.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per our offline discussion, we will address this in the follow-up work of fully enabling R2R builds