diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/CreateMultiDexMainDexClassList.cs b/src/Xamarin.Android.Build.Tasks/Tasks/CreateMultiDexMainDexClassList.cs index 6afdaa44d16..36faf3a82b7 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/CreateMultiDexMainDexClassList.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/CreateMultiDexMainDexClassList.cs @@ -1,4 +1,4 @@ -// Copyright (C) 2011 Xamarin, Inc. All rights reserved. +// Copyright (C) 2011 Xamarin, Inc. All rights reserved. using System; using System.Collections.Generic; @@ -12,13 +12,16 @@ namespace Xamarin.Android.Tasks { - public class CreateMultiDexMainDexClassList : ToolTask + public class CreateMultiDexMainDexClassList : JavaToolTask { [Required] public string ClassesOutputDirectory { get; set; } [Required] - public string ProguardHome { get; set; } + public string ProguardJarPath { get; set; } + + [Required] + public string AndroidSdkBuildToolsPath { get; set; } [Required] public ITaskItem[] JavaLibraries { get; set; } @@ -26,6 +29,10 @@ public class CreateMultiDexMainDexClassList : ToolTask public string MultiDexMainDexListFile { get; set; } public ITaskItem[] CustomMainDexListFiles { get; set; } + Action commandlineAction; + string tempJar; + bool writeOutputToKeepFile = false; + public override bool Execute () { Log.LogDebugMessage ("CreateMultiDexMainDexClassList"); @@ -35,7 +42,7 @@ public override bool Execute () Log.LogDebugTaskItems (" CustomMainDexListFiles:", CustomMainDexListFiles); Log.LogDebugMessage (" ToolExe: {0}", ToolExe); Log.LogDebugMessage (" ToolPath: {0}", ToolPath); - Log.LogDebugMessage (" ProguardHome: {0}", ProguardHome); + Log.LogDebugMessage (" ProguardJarPath: {0}", ProguardJarPath); if (CustomMainDexListFiles != null && CustomMainDexListFiles.Any ()) { var content = string.Concat (CustomMainDexListFiles.Select (i => File.ReadAllText (i.ItemSpec))); @@ -43,37 +50,61 @@ public override bool Execute () return true; } - EnvironmentVariables = MonoAndroidHelper.GetProguardEnvironmentVaribles (ProguardHome); + tempJar = Path.Combine (Path.GetTempPath (), Path.GetRandomFileName () + ".jar"); + commandlineAction = GenerateProguardCommands; + // run proguard first + var retval = base.Execute (); + if (!retval || Log.HasLoggedErrors) + return false; + + commandlineAction = GenerateMainDexListBuilderCommands; + // run java second + + return base.Execute () && !Log.HasLoggedErrors; - return base.Execute (); } protected override string GenerateCommandLineCommands () { var cmd = new CommandLineBuilder (); + commandlineAction (cmd); + return cmd.ToString (); + } - cmd.AppendSwitch ("--output"); - cmd.AppendFileNameIfNotNull (MultiDexMainDexListFile); - + void GenerateProguardCommands (CommandLineBuilder cmd) + { + var enclosingChar = OS.IsWindows ? "\"" : string.Empty; var jars = JavaLibraries.Select (i => i.ItemSpec).Concat (new string [] { ClassesOutputDirectory }); - string files = string.Join (Path.PathSeparator.ToString (), jars.Select (s => '\'' + s + '\'')); - if (OS.IsWindows) - cmd.AppendSwitch ('"' + files + '"'); - else - cmd.AppendSwitch (files); - - return cmd.ToString (); + cmd.AppendSwitchIfNotNull ("-jar ", ProguardJarPath); + cmd.AppendSwitchUnquotedIfNotNull ("-injars ", $"{enclosingChar}'" + string.Join ($"'{Path.PathSeparator}'", jars) + $"'{enclosingChar}"); + cmd.AppendSwitch ("-dontwarn"); + cmd.AppendSwitch ("-forceprocessing"); + cmd.AppendSwitchIfNotNull ("-outjars ", tempJar); + cmd.AppendSwitchIfNotNull ("-libraryjars ", $"'{Path.Combine (AndroidSdkBuildToolsPath, "lib", "shrinkedAndroid.jar")}'"); + cmd.AppendSwitch ("-dontoptimize"); + cmd.AppendSwitch ("-dontobfuscate"); + cmd.AppendSwitch ("-dontpreverify"); + cmd.AppendSwitchIfNotNull ("-include ", $"'{Path.Combine (AndroidSdkBuildToolsPath, "mainDexClasses.rules")}'"); } - protected override string ToolName { - get { - return OS.IsWindows ? "mainDexClasses.bat" : "mainDexClasses"; - } + void GenerateMainDexListBuilderCommands(CommandLineBuilder cmd) + { + var jars = JavaLibraries.Select (i => i.ItemSpec).Concat (new string [] { ClassesOutputDirectory }); + cmd.AppendSwitchIfNotNull ("-Djava.ext.dirs=", Path.Combine (AndroidSdkBuildToolsPath, "lib")); + cmd.AppendSwitch ("com.android.multidex.MainDexListBuilder"); + cmd.AppendSwitch (tempJar); + cmd.AppendSwitchUnquotedIfNotNull ("", "\"" + string.Join ($"{Path.PathSeparator}", jars) + "\""); + writeOutputToKeepFile = true; } - protected override string GenerateFullPathToTool () + protected override void LogEventsFromTextOutput (string singleLine, MessageImportance messageImportance) { - return Path.Combine (ToolPath, ToolExe); + var match = CodeErrorRegEx.Match (singleLine); + var exceptionMatch = ExceptionRegEx.Match (singleLine); + + if (writeOutputToKeepFile && !match.Success && !exceptionMatch.Success) + File.AppendAllText (MultiDexMainDexListFile, singleLine); + base.LogEventsFromTextOutput (singleLine, messageImportance); } } } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/JavaToolTask.cs b/src/Xamarin.Android.Build.Tasks/Tasks/JavaToolTask.cs index c646005cc23..d6c34399623 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/JavaToolTask.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/JavaToolTask.cs @@ -66,8 +66,8 @@ at com.android.dx.command.dexer.Main.main(Main.java:215) at com.android.dx.command.Main.main(Main.java:106) */ const string ExceptionRegExString = @"(?java.lang.+):(?.+)"; - Regex codeErrorRegEx = new Regex (CodeErrorRegExString, RegexOptions.Compiled); - Regex exceptionRegEx = new Regex (ExceptionRegExString, RegexOptions.Compiled); + protected static readonly Regex CodeErrorRegEx = new Regex (CodeErrorRegExString, RegexOptions.Compiled); + protected static readonly Regex ExceptionRegEx = new Regex (ExceptionRegExString, RegexOptions.Compiled); bool foundError = false; List errorLines = new List (); StringBuilder errorText = new StringBuilder (); @@ -114,8 +114,8 @@ void LogFromException (string exception, string error) { bool ProcessOutput (string singleLine) { - var match = codeErrorRegEx.Match (singleLine); - var exceptionMatch = exceptionRegEx.Match (singleLine); + var match = CodeErrorRegEx.Match (singleLine); + var exceptionMatch = ExceptionRegEx.Match (singleLine); if (match.Success) { if (!string.IsNullOrEmpty (file)) { @@ -157,8 +157,8 @@ bool ProcessOutput (string singleLine) protected override void LogEventsFromTextOutput (string singleLine, MessageImportance messageImportance) { - var match = codeErrorRegEx.Match (singleLine); - var exceptionMatch = exceptionRegEx.Match (singleLine); + var match = CodeErrorRegEx.Match (singleLine); + var exceptionMatch = ExceptionRegEx.Match (singleLine); if (match.Success || exceptionMatch.Success) { Log.LogMessage (MessageImportance.High, singleLine); diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index ad5fdad002d..bf1d1f2eefb 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -1950,9 +1950,10 @@ because xbuild doesn't support framework reference assemblies.