forked from dotnet/android
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Xamarin.Android.Build.Tasks] Desugar works without ProGuard (dotnet#…
…1973) Looking into a customer's binding project, usage of `$(AndroidEnableDesugar)` was causing a crash at runtime where the `mono.MonoRuntimeProvider` type was completely missing from the `app.apk`. Looking into it further, it seemed that our desugar support only worked when used with ProGuard or MultiDex. What was happening: - The `<Desugar/>` MSBuild task "desugars" the Xamarin.Android app code into a `__app_classes__.jar` file - However `__app_classes__.jar` was not added to the `OutputJars` output property - In `Xamarin.Android.Common.targets`, `@(_AlternativeJarForAppDx)` is used for the input to `javac`, which does not contain any of the Xamarin.Android app's Java code! In fact, a workaround for the customer's project, was to add the following to their Xamarin.Android app project file: <ItemGroup> <_AlternativeJarForAppDx Include="$(IntermediateOutputPath)android\bin\desugared\__app_classes__.jar" /> </ItemGroup> -- which was less than ideal. So before I fixed the issue, I improved our tests: - Added a `DexUtils` class that invokes the `dexdump` command, so we can assert that a dex file contains a specific Java class - Added `AndroidSdkDirectory` and `AndroidNdkDirectory` properties to `Xamarin.ProjectTools`, since I needed the Android SDK path to use `dexdump` - Fixed a bug where we need to use `Environment.SpecialFolder.UserProfile`, or the `android-toolchain\sdk` directory is not found on Windows - Added an assertion to the desugar tests, checking that `Lmono/MonoRuntimeProvider;` exists in the dex file - The desugar tests should also `ThrowOnBuildFailure` if desugar is enabled Next, the fixes for desugar support: - We no longer need `Desugar.InputClassesDirectory`, and do not need to generate `__app_classes__.jar`, since it was not being used at all anyway. - In `Xamarin.Android.Common.targets` we should include `classes.zip` in the `@(_AlternativeJarForAppDx)` item group. - I updated the `<Desugar/>` task to our new pattern of only logging `[Output]` properties The new tests are now green! Note: I tried *including* `__app_classes__.jar` at first, but proguard commands were failing. When the app code was "desugared", required attributes were removed such as `@Keep`. Since D8/R8 is the way forward in the future, I thought it simpler to just omit the creation of `__app_classes__.jar`.
- Loading branch information
1 parent
ab70b2d
commit 5995f0c
Showing
6 changed files
with
110 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Utilities/DexUtils.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using Xamarin.Android.Tools; | ||
|
||
namespace Xamarin.ProjectTools | ||
{ | ||
public static class DexUtils | ||
{ | ||
/// <summary> | ||
/// Runs the dexdump command to see if a class exists in a dex file | ||
/// dexdump returns data of the form: | ||
/// Class descriptor : 'Landroid/app/ActivityTracker;' | ||
/// </summary> | ||
/// <param name="className">A Java class name of the form 'Landroid/app/ActivityTracker;'</param> | ||
public static bool ContainsClass (string className, string dexFile, string androidSdkDirectory) | ||
{ | ||
bool containsClass = false; | ||
DataReceivedEventHandler handler = (s, e) => { | ||
if (e.Data != null && e.Data.Contains ("Class descriptor") && e.Data.Contains (className)) | ||
containsClass = true; | ||
}; | ||
|
||
var androidSdk = new AndroidSdkInfo ((l, m) => { | ||
Console.WriteLine ($"{l}: {m}"); | ||
if (l == TraceLevel.Error) { | ||
throw new Exception (m); | ||
} | ||
}, androidSdkDirectory); | ||
var buildToolsPath = androidSdk.GetBuildToolsPaths ().FirstOrDefault (); | ||
if (string.IsNullOrEmpty (buildToolsPath)) { | ||
throw new Exception ($"Unable to find build-tools in `{androidSdkDirectory}`!"); | ||
} | ||
|
||
var psi = new ProcessStartInfo { | ||
FileName = Path.Combine (buildToolsPath, "dexdump"), | ||
Arguments = $"\"{dexFile}\"", | ||
CreateNoWindow = true, | ||
WindowStyle = ProcessWindowStyle.Hidden, | ||
UseShellExecute = false, | ||
RedirectStandardError = true, | ||
RedirectStandardOutput = true, | ||
}; | ||
var builder = new StringBuilder (); | ||
using (var p = new Process { StartInfo = psi }) { | ||
p.ErrorDataReceived += handler; | ||
p.OutputDataReceived += handler; | ||
|
||
p.Start (); | ||
p.BeginErrorReadLine (); | ||
p.BeginOutputReadLine (); | ||
p.WaitForExit (); | ||
} | ||
|
||
return containsClass; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters