Skip to content

Conversation

@jonathanpeppers
Copy link
Member

A customer reported a build error such as:

C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\33.0.46\targets\Microsoft.Android.Sdk.AndroidLibraries.targets(77,5):
error XACAAR7014: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Text.StringBuilder.ToString()
at Xamarin.Android.Tasks.CreateAar.RunTask()
at Microsoft.Android.Build.Tasks.AndroidTask.Execute()

Somewhere here:

https://github.com/xamarin/xamarin-android/blob/c31f3eda63a16e412a39fa61eb0f885be3c5f543/src/Xamarin.Android.Build.Tasks/Tasks/CreateAar.cs#L108-L114

The problem appears to be triggered by:

ProguardConfigurationFiles=
~\.nuget\packages\xamarin.androidx.versionedparcelable\1.1.1.15\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.lifecycle.runtime\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.core\1.9.0.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.savedstate\1.2.0.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.recyclerview\1.2.1.7\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.lifecycle.viewmodel\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.lifecycle.viewmodelsavedstate\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.fragment\1.5.3.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.vectordrawable.animated\1.1.0.14\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.transition\1.4.1.8\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.startup.startupruntime\1.1.1.2\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.lifecycle.process\2.5.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.coordinatorlayout\1.2.0.3\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.appcompat\1.5.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.google.android.material\1.7.0\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.window\1.0.0.10\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.navigation.common\2.5.2.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.navigation.ui\2.5.2.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
~\.nuget\packages\xamarin.androidx.media\1.6.0.2\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
..\path\to\projectreference\obj\Debug\lp\160\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\155\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\161\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\162\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\156\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\157\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\163\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\164\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\165\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\166\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\167\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\170\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\168\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\169\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\171\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\172\jl\proguard.txt
..\path\to\projectreference\obj\Debug\lp\173\jl\proguard.txt

We have a compounding issue:

  • AndroidX NuGets add proguard.txt files to class libraries

  • These make it to YourClassLibrary.aar

  • You might have class libraries that reference other class libraries

  • You end up with N^2 proguard.txt files and hit OOM.

Step 1 to fix this is to simply not add @(ProguardConfiguration) from the AndroidX NuGets for class libraries.

I will investigate how we solve the obj\Debug\lp\173\jl\proguard.txt entries in xamarin-android.

A customer reported a build error such as:

    C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\33.0.46\targets\Microsoft.Android.Sdk.AndroidLibraries.targets(77,5):
    error XACAAR7014: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
    at System.Text.StringBuilder.ToString()
    at Xamarin.Android.Tasks.CreateAar.RunTask()
    at Microsoft.Android.Build.Tasks.AndroidTask.Execute()

Somewhere here:

https://github.com/xamarin/xamarin-android/blob/c31f3eda63a16e412a39fa61eb0f885be3c5f543/src/Xamarin.Android.Build.Tasks/Tasks/CreateAar.cs#L108-L114

The problem appears to be triggered by:

    ProguardConfigurationFiles=
    ~\.nuget\packages\xamarin.androidx.versionedparcelable\1.1.1.15\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.lifecycle.runtime\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.core\1.9.0.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.savedstate\1.2.0.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.recyclerview\1.2.1.7\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.lifecycle.viewmodel\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.lifecycle.viewmodelsavedstate\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.fragment\1.5.3.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.vectordrawable.animated\1.1.0.14\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.transition\1.4.1.8\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.startup.startupruntime\1.1.1.2\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.lifecycle.process\2.5.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.coordinatorlayout\1.2.0.3\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.appcompat\1.5.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.google.android.material\1.7.0\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.window\1.0.0.10\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.navigation.common\2.5.2.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.navigation.ui\2.5.2.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.media\1.6.0.2\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\160\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\155\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\161\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\162\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\156\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\157\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\163\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\164\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\165\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\166\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\167\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\170\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\168\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\169\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\171\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\172\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\173\jl\proguard.txt

We have a compounding issue:

* AndroidX NuGets add `proguard.txt` files to class libraries

* These make it to `YourClassLibrary.aar`

* You might have class libraries that reference other class libraries

* You end up with N^2 `proguard.txt` files and hit OOM.

Step 1 to fix this is to simply not add `@(ProguardConfiguration)`
from the AndroidX NuGets for class libraries.

I will investigate how we solve the `obj\Debug\lp\173\jl\proguard.txt`
entries in xamarin-android.
@jonathanpeppers jonathanpeppers requested review from jpobst and moljac May 9, 2023 19:40
Copy link
Contributor

@jpobst jpobst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not extremely confident about Proguard files, but I think this makes sense.

@jonathanpeppers
Copy link
Member Author

proguard.txt files would mostly be used here:

https://github.com/xamarin/xamarin-android/blob/7e8215f71034a738fbafb815e3bf5454b5c6bd6a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.D8.targets#L76

Which this would only run for "app" projects.

jonathanpeppers added a commit to jonathanpeppers/xamarin-android that referenced this pull request May 9, 2023
…aries

Context: dotnet/android-libraries#729

A customer reported a build error such as:

    C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\33.0.46\targets\Microsoft.Android.Sdk.AndroidLibraries.targets(77,5):
    error XACAAR7014: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
    at System.Text.StringBuilder.ToString()
    at Xamarin.Android.Tasks.CreateAar.RunTask()
    at Microsoft.Android.Build.Tasks.AndroidTask.Execute()

Somewhere here:

https://github.com/xamarin/xamarin-android/blob/c31f3eda63a16e412a39fa61eb0f885be3c5f543/src/Xamarin.Android.Build.Tasks/Tasks/CreateAar.cs#L108-L114

The problem appears to be triggered by:

    ProguardConfigurationFiles=
    ~\.nuget\packages\xamarin.androidx.versionedparcelable\1.1.1.15\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.lifecycle.runtime\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.core\1.9.0.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.savedstate\1.2.0.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.recyclerview\1.2.1.7\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.lifecycle.viewmodel\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.lifecycle.viewmodelsavedstate\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.fragment\1.5.3.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.vectordrawable.animated\1.1.0.14\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.transition\1.4.1.8\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.startup.startupruntime\1.1.1.2\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.lifecycle.process\2.5.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.coordinatorlayout\1.2.0.3\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.appcompat\1.5.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.google.android.material\1.7.0\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.window\1.0.0.10\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.navigation.common\2.5.2.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.navigation.ui\2.5.2.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ~\.nuget\packages\xamarin.androidx.media\1.6.0.2\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\160\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\155\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\161\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\162\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\156\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\157\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\163\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\164\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\165\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\166\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\167\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\170\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\168\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\169\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\171\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\172\jl\proguard.txt
    ..\path\to\projectreference\obj\Debug\lp\173\jl\proguard.txt

We have a compounding issue:

* `.aar` files that contain `proguard.txt` files are added to class
  libraries

* These make it to `YourClassLibrary.aar`

* You might have class libraries that reference other class libraries

* You end up with N^2 `proguard.txt` files and hit OOM.

I believe this problem was partially introduced in c537dd2, but we
didn't notice until now. The AndroidX NuGet packages also cause this
problem, but in a different way as seen in dotnet/android-libraries#729.

A solution here is that `<ResolveLibraryProjectImports/>` should
simply ignore `proguard.txt` files in class libraries. They are only
actually needed in "app" projects where the `<R8/>` MSBuild task would
use them.

I could reproduce this in a test using an `.aar` from maven that
contains a `proguard.txt`:

https://mvnrepository.com/artifact/androidx.core/core/1.10.0

And then just assert the `proguard.txt` contents don't make it to
`MyClassLibrary.aar`.
@jonathanpeppers jonathanpeppers merged commit f0a63f4 into main May 10, 2023
@jonathanpeppers jonathanpeppers deleted the ProguardConfiguration branch May 10, 2023 20:44
@jonathanpeppers
Copy link
Member Author

jonathanpeppers added a commit to jonathanpeppers/GooglePlayServicesComponents that referenced this pull request May 10, 2023
Context: dotnet/android-libraries#729
Context: dotnet/android#8025

A customer reported a build error such as:

    C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\33.0.46\targets\Microsoft.Android.Sdk.AndroidLibraries.targets(77,5):
    error XACAAR7014: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
    at System.Text.StringBuilder.ToString()
    at Xamarin.Android.Tasks.CreateAar.RunTask()
    at Microsoft.Android.Build.Tasks.AndroidTask.Execute()

Somewhere here:

https://github.com/xamarin/xamarin-android/blob/c31f3eda63a16e412a39fa61eb0f885be3c5f543/src/Xamarin.Android.Build.Tasks/Tasks/CreateAar.cs#L108-L114

We have a compounding issue:

* Google Play Services NuGets add `proguard.txt` files to class libraries

* These make it to `YourClassLibrary.aar`

* You might have class libraries that reference other class libraries

* You end up with N^2 `proguard.txt` files and hit OOM.

Step 1 to fix this is to simply not add `@(ProguardConfiguration)`
from the Google Play Services NuGets for class libraries.

We can solve the `obj\Debug\lp\173\jl\proguard.txt`
entries in dotnet/android#8025.
jonathanpeppers added a commit to xamarin/GooglePlayServicesComponents that referenced this pull request May 11, 2023
Context: dotnet/android-libraries#729
Context: dotnet/android#8025

A customer reported a build error such as:

    C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\33.0.46\targets\Microsoft.Android.Sdk.AndroidLibraries.targets(77,5):
    error XACAAR7014: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
    at System.Text.StringBuilder.ToString()
    at Xamarin.Android.Tasks.CreateAar.RunTask()
    at Microsoft.Android.Build.Tasks.AndroidTask.Execute()

Somewhere here:

https://github.com/xamarin/xamarin-android/blob/c31f3eda63a16e412a39fa61eb0f885be3c5f543/src/Xamarin.Android.Build.Tasks/Tasks/CreateAar.cs#L108-L114

We have a compounding issue:

* Google Play Services NuGets add `proguard.txt` files to class libraries

* These make it to `YourClassLibrary.aar`

* You might have class libraries that reference other class libraries

* You end up with N^2 `proguard.txt` files and hit OOM.

Step 1 to fix this is to simply not add `@(ProguardConfiguration)`
from the Google Play Services NuGets for class libraries.

We can solve the `obj\Debug\lp\173\jl\proguard.txt`
entries in dotnet/android#8025.
jonpryor pushed a commit to dotnet/android that referenced this pull request May 15, 2023
Context: c537dd2
Context: dotnet/android-libraries#729
Context: xamarin/GooglePlayServicesComponents#774

A customer reported a build error such as:

	C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\33.0.46\targets\Microsoft.Android.Sdk.AndroidLibraries.targets(77,5):
	error XACAAR7014: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
	   at System.Text.StringBuilder.ToString()
	   at Xamarin.Android.Tasks.CreateAar.RunTask()
	   at Microsoft.Android.Build.Tasks.AndroidTask.Execute()

Somewhere within [`<CreateAar/>`][0]:

	if (ProguardConfigurationFiles != null) {
	    var sb = new StringBuilder ();
	    foreach (var file in ProguardConfigurationFiles) {
	        sb.AppendLine (File.ReadAllText (file.ItemSpec));
	    }
	    aar.AddEntry ("proguard.txt", sb.ToString (), Files.UTF8withoutBOM);
	}

The problem appears to be triggered by:

 1. Library project `Lib.csproj` which bind `.aar` files include the
    `proguard.txt` from the `.aar` into the output `Lib.aar`, as
    `Lib.aar!proguard.txt`.

 2. Library project `References.csproj` which has a `@(Reference)` to
    `Lib.csproj` will include the contents of `Lib.aar!proguard.txt`
    into `References.aar!proguard.txt`.  If `References.csproj` has a
    `@(PackageReference)` which has `AnotherLib.aar`, then
    `AnotherLib.aar!proguard.txt` will *also* be copied into
    `References.aar!proguard.txt`.
    (Repeat for all `@(Reference)` and `@(projectreference)`.)
    (Note combinatorial explosion in `proguard.txt` size…)

 3. App project `App.csproj` references (2), merging all the contents
    of all the `proguard.txt` files from all the `.aar` files into a
    single unified `proguard.txt` file.

If the project has lots of library projects or package references,
step (3) could OOM.  "Lots" of references, such as:

	ProguardConfigurationFiles=
	    ~\.nuget\packages\xamarin.androidx.versionedparcelable\1.1.1.15\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.lifecycle.runtime\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.core\1.9.0.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.savedstate\1.2.0.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.recyclerview\1.2.1.7\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.lifecycle.viewmodel\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.lifecycle.viewmodelsavedstate\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.fragment\1.5.3.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.vectordrawable.animated\1.1.0.14\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.transition\1.4.1.8\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.startup.startupruntime\1.1.1.2\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.lifecycle.process\2.5.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.coordinatorlayout\1.2.0.3\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.appcompat\1.5.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.google.android.material\1.7.0\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.window\1.0.0.10\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.navigation.common\2.5.2.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.navigation.ui\2.5.2.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.media\1.6.0.2\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\160\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\155\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\161\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\162\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\156\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\157\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\163\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\164\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\165\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\166\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\167\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\170\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\168\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\169\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\171\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\172\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\173\jl\proguard.txt
	    …

I believe this problem was partially introduced in c537dd2, but we
didn't notice until now.  The AndroidX NuGet packages also cause this
problem, but in a different way as seen in dotnet/android-libraries#729 and
xamarin/GooglePlayServicesComponents#774.

A solution here is that `<ResolveLibraryProjectImports/>` should
simply ignore `proguard.txt` files in class libraries.  They are only
actually needed in "app" projects where the `<R8/>` MSBuild task
would use them.

I could reproduce this in a test using an `.aar` from maven that
contains a `proguard.txt`:

  * <https://mvnrepository.com/artifact/androidx.core/core/1.10.0>

And then just assert the `proguard.txt` contents don't make it to
`MyClassLibrary.aar`.

Note: dotnet/android-libraries#729 and xamarin/GooglePlayServicesComponents#774
update the NuGet Packages so that `proguard.txt` files are only
added to `@(ProguardConfiguration)` when `$(AndroidApplication)`=True.
This should also help prevent the OOM scenario.

[0]: https://github.com/xamarin/xamarin-android/blob/c31f3eda63a16e412a39fa61eb0f885be3c5f543/src/Xamarin.Android.Build.Tasks/Tasks/CreateAar.cs#L108-L114
jonathanpeppers added a commit to dotnet/android that referenced this pull request May 25, 2023
Context: c537dd2
Context: dotnet/android-libraries#729
Context: xamarin/GooglePlayServicesComponents#774

A customer reported a build error such as:

	C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\33.0.46\targets\Microsoft.Android.Sdk.AndroidLibraries.targets(77,5):
	error XACAAR7014: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
	   at System.Text.StringBuilder.ToString()
	   at Xamarin.Android.Tasks.CreateAar.RunTask()
	   at Microsoft.Android.Build.Tasks.AndroidTask.Execute()

Somewhere within [`<CreateAar/>`][0]:

	if (ProguardConfigurationFiles != null) {
	    var sb = new StringBuilder ();
	    foreach (var file in ProguardConfigurationFiles) {
	        sb.AppendLine (File.ReadAllText (file.ItemSpec));
	    }
	    aar.AddEntry ("proguard.txt", sb.ToString (), Files.UTF8withoutBOM);
	}

The problem appears to be triggered by:

 1. Library project `Lib.csproj` which bind `.aar` files include the
    `proguard.txt` from the `.aar` into the output `Lib.aar`, as
    `Lib.aar!proguard.txt`.

 2. Library project `References.csproj` which has a `@(Reference)` to
    `Lib.csproj` will include the contents of `Lib.aar!proguard.txt`
    into `References.aar!proguard.txt`.  If `References.csproj` has a
    `@(PackageReference)` which has `AnotherLib.aar`, then
    `AnotherLib.aar!proguard.txt` will *also* be copied into
    `References.aar!proguard.txt`.
    (Repeat for all `@(Reference)` and `@(projectreference)`.)
    (Note combinatorial explosion in `proguard.txt` size…)

 3. App project `App.csproj` references (2), merging all the contents
    of all the `proguard.txt` files from all the `.aar` files into a
    single unified `proguard.txt` file.

If the project has lots of library projects or package references,
step (3) could OOM.  "Lots" of references, such as:

	ProguardConfigurationFiles=
	    ~\.nuget\packages\xamarin.androidx.versionedparcelable\1.1.1.15\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.lifecycle.runtime\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.core\1.9.0.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.savedstate\1.2.0.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.recyclerview\1.2.1.7\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.lifecycle.viewmodel\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.lifecycle.viewmodelsavedstate\2.5.1.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.fragment\1.5.3.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.vectordrawable.animated\1.1.0.14\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.transition\1.4.1.8\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.startup.startupruntime\1.1.1.2\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.lifecycle.process\2.5.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.coordinatorlayout\1.2.0.3\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.appcompat\1.5.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.google.android.material\1.7.0\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.window\1.0.0.10\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.navigation.common\2.5.2.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.navigation.ui\2.5.2.1\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ~\.nuget\packages\xamarin.androidx.media\1.6.0.2\buildTransitive\net6.0-android31.0\..\..\proguard\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\160\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\155\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\161\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\162\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\156\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\157\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\163\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\164\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\165\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\166\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\167\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\170\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\168\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\169\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\171\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\172\jl\proguard.txt
	    ..\path\to\projectreference\obj\Debug\lp\173\jl\proguard.txt
	    …

I believe this problem was partially introduced in c537dd2, but we
didn't notice until now.  The AndroidX NuGet packages also cause this
problem, but in a different way as seen in dotnet/android-libraries#729 and
xamarin/GooglePlayServicesComponents#774.

A solution here is that `<ResolveLibraryProjectImports/>` should
simply ignore `proguard.txt` files in class libraries.  They are only
actually needed in "app" projects where the `<R8/>` MSBuild task
would use them.

I could reproduce this in a test using an `.aar` from maven that
contains a `proguard.txt`:

  * <https://mvnrepository.com/artifact/androidx.core/core/1.10.0>

And then just assert the `proguard.txt` contents don't make it to
`MyClassLibrary.aar`.

Note: dotnet/android-libraries#729 and xamarin/GooglePlayServicesComponents#774
update the NuGet Packages so that `proguard.txt` files are only
added to `@(ProguardConfiguration)` when `$(AndroidApplication)`=True.
This should also help prevent the OOM scenario.

[0]: https://github.com/xamarin/xamarin-android/blob/c31f3eda63a16e412a39fa61eb0f885be3c5f543/src/Xamarin.Android.Build.Tasks/Tasks/CreateAar.cs#L108-L114
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants