Skip to content
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

Building a Maui App for Android is extremely slow when EmbedAssembliesIntoApk is enabled (net9) #9455

Open
AlexanderEgorov opened this issue Oct 23, 2024 · 8 comments
Assignees
Labels
Area: App+Library Build Issues when building Library projects or Application projects.

Comments

@AlexanderEgorov
Copy link

Description

Building a MAUI project targeting net9.0-android is much slower when EmbedAssembliesIntoApk is enabled compared to building under net8.0-android (500s in net9 vs 90s in net8). Most of the time is spent on the _BuildApkEmbed process.

Steps to Reproduce

  1. Create a new application with dotnet new maui -n MauiBlankApp targeting net9.
  2. Build it with the following command:
    dotnet build MauiBlankApp.csproj -p:Configuration=Debug -p:TargetFramework=net9.0-android -p:EmbedAssembliesIntoApk=true -p:AndroidSdkDirectory=...

Link to public reproduction project repository

No response

Version with bug

9.0.0-rc.2.24503.2

Is this a regression from previous behavior?

Yes, this used to work in .NET MAUI

Last version that worked well

8.0.92 SR9.2

Affected platforms

Android

Affected platform versions

No response

Did you find any workaround?

No response

Relevant log output

No response

@PureWeen PureWeen transferred this issue from dotnet/maui Oct 23, 2024
@dotnet-policy-service dotnet-policy-service bot added the needs-triage Issues that need to be assigned. label Oct 23, 2024
@jpobst
Copy link
Contributor

jpobst commented Oct 24, 2024

Can you create a .binlog for each one so we can compare the differences?

Run the command line again with -bl to create a msbuild.binlog in the current directory.

@jpobst jpobst added Area: App+Library Build Issues when building Library projects or Application projects. and removed needs-triage Issues that need to be assigned. labels Oct 24, 2024
@jonathanpeppers
Copy link
Member

jonathanpeppers commented Oct 24, 2024

Why do you have EmbedAssembliesIntoApk enabled? The feature called “fast deployment” is disabled by this setting.

@AlexanderEgorov
Copy link
Author

Why do you have EmbedAssembliesIntoApk enabled? The feature called “fast deployment” is disabled by this setting.

We have a test server which builds apk's, and then run it with our own script on emulators and real phones. But even using locally, our team prefer building with the EmbedAssembliesIntoApk option enabled, because it works more reliable.

We noticed some optimizations in the build process based on the resultant APK file size compared to net8. However, we would like to be able to disable these optimizations in Debug mode to get a faster build like it was in net8.

Can you create a .binlog for each one so we can compare the differences?

net8: https://github.com/AlexanderEgorov/dotnet-android--9455/blob/main/MauiBlankApp_net8/msbuild.binlog
net9: https://github.com/AlexanderEgorov/dotnet-android--9455/blob/main/MauiBlankApp_net9/msbuild.binlog

@JaneySprings
Copy link

Hi @jonathanpeppers ! I'm a developer of the .NET Meteor extension for VSCode. I also use this property for the debugging Android applications:
https://github.com/JaneySprings/DotNet.Meteor/blob/e4a567de61061f07d74fc28db83187297de01bcc/src/VSCode.Extension/providers/dotnetTaskProvider.ts#L30

I tried to support the _FastDev feature, but internal testing showed that it works very unstable.

I also want the build and launch processes to be the same, both for iOS or Maccatalyst or Windows, and for Android.

@dellis1972
Copy link
Contributor

In what way is the FastDev features "unstable" ? It would be helpful to have more information as to why ?
Is it a problem in our side or adb errors?

Turning FastDev off is always going to be slower because we have to not only build the apk from scratch, we also have to uninstall the app on the device before sending over the new one. All of this adds up.

@JaneySprings
Copy link

JaneySprings commented Oct 24, 2024

we also have to uninstall the app on the device before sending over the new one

As @AlexanderEgorov said, we don't use the dotnet -t:Run command. We are having problems with the build time of the apk file.

In what way is the FastDev features "unstable"

It works ~40% cases, but more often it doesn't.
Sometimes an application shows '.NET' splashscreen for 2-3min and closes.
Sometimes it shows me a main page, but debugging doesn't work. I see many adbd: connection refused messages in the logcat.

In the .NET Meteor extension I use the manual way:

  • ONLY build the application
  • run AVD, reverse all used ports (debugger or profiler or hotReload ...)
  • connect to debugger and send start debugger: sdb command

This method has been working for more than two years on all operating systems (Linux, MacOS, Windows) and for every platform (Maccatalyst, iOS, Windows, Android).

@jonathanpeppers
Copy link
Member

@JaneySprings we'd prefer if you could share a .binlog of the failures with fast deployment, and we should fix those instead: https://aka.ms/binlog

We'd prefer to fix that feature than improve a sub-optimal settings that fewer developers are using by default. Most of our developers just use the defaults (all settings just blank) inside Visual Studio.

@jpobst
Copy link
Contributor

jpobst commented Dec 10, 2024

For context on the reported issue, it appears to be a result of the "all managed assemblies are arch-specific" change.

In .NET 8, we would add (N assemblies + .pdbs) to the APK as "assets".

In .NET 9, for each of (N assemblies + .pdbs) x (supported ABIs), we:

  • Shell out to:
    • llvm-objcopy.EXE --add-section payload=obj\Debug\net9.0-android\android\assets\arm64-v8a\myproject.dll obj\Debug\net9.0-android\android-arm64\wrapped\lib_myproject.dll.so
  • Shell out to:
    • llvm-objcopy.EXE --set-section-flags payload=readonly,data --set-section-alignment payload=16384 obj\Debug\net9.0-android\android-arm64\wrapped\lib_myproject.dll.so
  • Add the file to the APK

We probably can't avoid the doubling of the involved files due to defaulting to 2 architectures. Users could use $(RuntimeIdentifiers) or dotnet build -r <rid> to only build a single arch if that's all they need and their tooling isn't automatically setting that for them.

Aside from that, it would be ideal if we could find a managed way of doing the llvm-objcopy.exe. It is expensive to launch 2 new processes for each assembly file. (Even for a single arch, the android template references 170+ framework assemblies.)

There is also work to be done to make the llvm-objcopy.exe parts incremental. For now, it appears to always run the full process for all assemblies for any change. Also, always running llvm-objcopy.exe bumps the assembly modified time, so assemblies have to be updated in the APK instead of keeping the existing same file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: App+Library Build Issues when building Library projects or Application projects.
Projects
None yet
Development

No branches or pull requests

5 participants