dotnet / android

.NET for Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#
MIT License
1.92k stars 525 forks source link

Building debug project with aapt2 enabled is very slow. #4095

Open tcs021 opened 4 years ago

tcs021 commented 4 years ago

Steps to Reproduce

  1. VS 2019 Version 16.4.2
  2. Set "Use incremental Android packaging system (aapt2)" to true (with Shared Runtime and Fast Deployment enabled)
  3. Build

https://gist.github.com/tcs021/7133d2b24cdddda2c120560f0da43d4a

Expected Behavior

Build takes 1-2 minutes

Actual Behavior

Build takes 7-10 minutes (2018 Mac Book Pro)

compile -o obj\Debug\90\flata\compiled.flata --dir obj\Debug\90\res is slow and being called three times, even when no resources have changed. The "res" directory has about 1000 files in it.

Reading about AAPT2 here https://developer.android.com/studio/command-line/aapt2 it mentions that calling with the --dir option does not allow it to do incremental compilation and does not recommend for large projects.

Also when building, then debugging, the aapt2 compile step is run again, even though nothing has changed.

Perhaps this is just not ready for a large project. If that is the case, what settings are recommend for best build & debug performance for a large project?

Version Information

VS 2019 Version 16.4.2

Details in Gist above

Log File

dellis1972 commented 4 years ago

@tcs021 sorry you are having trouble. Is there a way we can get the diagnostic build output for the issue? I suspect what is happening is something is causing the Compile target to run again which has not shown up in our test projects. If we can get a look at the diagnostic build output we can see which file(s) are causing that target to run and hopefully fix the issue or suggest a work around.

tcs021 commented 4 years ago

Included is a compressed BINLOG of a build that included changes. It looks like Aapt2Compile step ran three times, but I can't figure out why. If you could help figure that out I would greatly appreciate.

Thanks.

BuildWithChanges-FishFeed.Droid_Debug_AnyCPU_Build_2020-01-10T16_57_42.5208683-05_00.zip

jonathanpeppers commented 4 years ago

@tcs021 It looks like the usage of custom views (such as this example):

https://github.com/xamarin/xamarin-android/blob/2c5d9b1648f197b945450c25a7aa52464ec87c4a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Tasks/ConvertResourcesCasesTests.cs#L55

Is causing your build to be slower when using aapt2.

@dellis1972 I remember we looked at that to make sure it wasn't happening when there are no custom views at all, is there a way we could make it be closer to the time aapt(1) takes? Somehow skip the second aapt2 compile?

Also a side note:

Input file "C:\Users\Todd\src\fishfeed\Droid\FishFeed.Droid.csproj.user" is newer than output file "obj\Debug\90\stamp\_GeneratePackageManagerJava.stamp".

It looks like usage of $(MSBuildAllProjects) as an Input will include .user files with VS Windows. These change when you toggle the device dropdown:

> cat MyApp.csproj.user
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <SelectedDevice>x86</SelectedDevice>
    <DefaultDevice>x86</DefaultDevice>
    <AndroidDesignerPreferredTheme>AppTheme</AndroidDesignerPreferredTheme>
    <AndroidDesignerPreferredDevice>Nexus 4</AndroidDesignerPreferredDevice>
  </PropertyGroup>
</Project>

I'll see if we can do anything there... We don't want all of our targets re-running when you change the device you are deploying to.

tcs021 commented 4 years ago

@jonathanpeppers Thanks so much for the quick response.

Is there anything we might be able to do to work around the current behavior? Even going back to aapt gives us a long build time (maybe 4 minutes vs 6 minutes with aapt2).

Also is there any other info that I can share that may help?

Thanks again.

jonathanpeppers commented 4 years ago

@tcs021 just to check, you mostly get these long build times when changing AndroidResource files?

If you change C# code is it quite a bit faster?

tcs021 commented 4 years ago

It is sometimes much faster, when it decides that the Android app project does not need to build.

It seems to compile the resources most times, sometimes when just code changes, and sometimes with no changes.

jonathanpeppers commented 4 years ago

@tcs021 if you see it running aapt even when you didn't change any AndroidResource files, send another build log and we can look into that.

One issue that springs to mind is what I fixed here: https://github.com/xamarin/xamarin-android/pull/3837

It seemed that non-existent AndroidResource files did not give an error, but also triggered the MSBuild targets that run aapt to run every time. You might check if you see something like:

Building target "_CompileResources" completely.
Input file "Resources\layout\noexist.xml" does not exist.

Check if the file exists or not, and remove from your project.

justinwojo commented 4 years ago

I'm glad I found this thread. We've been battling this issue now for quite a while, and just couldn't figure out what was going on. Turns out it was the issue where the csproj file was referencing a drawable that didn't exist. Once I removed it from the csproj file, our deployments went from minutes to seconds. Phew.

jonathanpeppers commented 4 years ago

@justinwojo in the 16.5 preview, it should give an error the same as if you were missing a .cs file. I'm glad I found this bug, too!