From 5ac1a691576cfbaf41cdb186ee9ac52d07582753 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Mon, 27 Nov 2017 11:32:21 -0600 Subject: [PATCH] [Xamarin.Android.Build.Tasks] added filter to proguard commands Context: https://bugzilla.xamarin.com/show_bug.cgi?id=56834 A default multi-dex application will print a warning to the console such as: ``` Warning: can't write resource [META-INF/MANIFEST.MF] (Duplicate zip entry [android-support-multidex.jar:META-INF/MANIFEST.MF]) ``` This is due to most jar files containing a `META-INF/MANIFEST.MF`, which really just needs to be excluded from the proguard command. We can do this by adding a filter to the end of each jar file passed via the `-injars` command line option. Changes: - Added a `$(_AndroidProguardInputJarFilter)` internal property, which defaults to `(!META-INF/MANIFEST.MF)` so we ignore the most common warning by default - Added a `ProguardInputJarFilter` property to the `` and `` tasks - Added assertions to multi-dex unit tests making sure we aren't getting the warning anymore - Minor fix to clear the `ghprbPullLongDescription` environment variable during tests, otherwise my PR/commit message causes my new test assertions to fail --- .../Tasks/CreateMultiDexMainDexClassList.cs | 4 +++- src/Xamarin.Android.Build.Tasks/Tasks/Proguard.cs | 4 +++- .../Tests/Xamarin.Android.Build.Tests/BuildTest.cs | 2 ++ .../Tests/Xamarin.ProjectTools/Common/Builder.cs | 3 +++ .../Xamarin.Android.Common.targets | 3 +++ 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/CreateMultiDexMainDexClassList.cs b/src/Xamarin.Android.Build.Tasks/Tasks/CreateMultiDexMainDexClassList.cs index 98c7de91209..d2a21bd3ed5 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/CreateMultiDexMainDexClassList.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/CreateMultiDexMainDexClassList.cs @@ -28,6 +28,7 @@ public class CreateMultiDexMainDexClassList : JavaToolTask public string MultiDexMainDexListFile { get; set; } public ITaskItem[] CustomMainDexListFiles { get; set; } + public string ProguardInputJarFilter { get; set; } Action commandlineAction; string tempJar; @@ -43,6 +44,7 @@ public override bool Execute () Log.LogDebugMessage (" ToolExe: {0}", ToolExe); Log.LogDebugMessage (" ToolPath: {0}", ToolPath); Log.LogDebugMessage (" ProguardJarPath: {0}", ProguardJarPath); + Log.LogDebugMessage (" ProguardInputJarFilter: {0}", ProguardInputJarFilter); if (CustomMainDexListFiles != null && CustomMainDexListFiles.Any ()) { var content = string.Concat (CustomMainDexListFiles.Select (i => File.ReadAllText (i.ItemSpec))); @@ -76,7 +78,7 @@ void GenerateProguardCommands (CommandLineBuilder cmd) var enclosingChar = OS.IsWindows ? "\"" : string.Empty; var jars = JavaLibraries.Select (i => i.ItemSpec).Concat (new string [] { Path.Combine (ClassesOutputDirectory, "classes.zip") }); cmd.AppendSwitchIfNotNull ("-jar ", ProguardJarPath); - cmd.AppendSwitchUnquotedIfNotNull ("-injars ", $"{enclosingChar}'" + string.Join ($"'{Path.PathSeparator}'", jars) + $"'{enclosingChar}"); + cmd.AppendSwitchUnquotedIfNotNull ("-injars ", $"{enclosingChar}'" + string.Join ($"{ProguardInputJarFilter}'{Path.PathSeparator}'", jars) + $"{ProguardInputJarFilter}'{enclosingChar}"); cmd.AppendSwitch ("-dontwarn"); cmd.AppendSwitch ("-forceprocessing"); cmd.AppendSwitchIfNotNull ("-outjars ", tempJar); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Proguard.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Proguard.cs index 0c6c31dac2d..31f716edc09 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Proguard.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Proguard.cs @@ -69,6 +69,7 @@ public class Proguard : ToolTask public string PrintSeedsOutput { get; set; } public string PrintUsageOutput { get; set; } public string PrintMappingOutput { get; set; } + public string ProguardInputJarFilter { get; set; } protected override string ToolName { get { @@ -98,6 +99,7 @@ public override bool Execute () Log.LogDebugMessage (" DumpOutput: {0}", DumpOutput); Log.LogDebugMessage (" PrintSeedsOutput: {0}", PrintSeedsOutput); Log.LogDebugMessage (" PrintMappingOutput: {0}", PrintMappingOutput); + Log.LogDebugMessage (" ProguardInputJarFilter: {0}", ProguardInputJarFilter); EnvironmentVariables = MonoAndroidHelper.GetProguardEnvironmentVaribles (ProguardHome); @@ -170,7 +172,7 @@ protected override string GenerateCommandLineCommands () foreach (var jarfile in ExternalJavaLibraries.Select (p => p.ItemSpec)) libjars.Add (jarfile); - cmd.AppendSwitchUnquotedIfNotNull ("-injars ", $"{enclosingChar}'" + string.Join ($"'{Path.PathSeparator}'", injars.Distinct ()) + $"'{enclosingChar}"); + cmd.AppendSwitchUnquotedIfNotNull ("-injars ", $"{enclosingChar}'" + string.Join ($"{ProguardInputJarFilter}'{Path.PathSeparator}'", injars.Distinct ()) + $"{ProguardInputJarFilter}'{enclosingChar}"); cmd.AppendSwitchUnquotedIfNotNull ("-libraryjars ", $"{enclosingChar}'" + string.Join ($"'{Path.PathSeparator}'", libjars.Distinct ()) + $"'{enclosingChar}"); diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs index 9613be47fa3..aababd71517 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest.cs @@ -391,6 +391,7 @@ public void BuildMultiDexApplication (bool useJackAndJill, string fxVersion) Assert.IsTrue (File.Exists (multidexKeepPath), "multidex.keep exists"); Assert.IsTrue (File.ReadAllLines (multidexKeepPath).Length > 1, "multidex.keep must contain more than one line."); Assert.IsTrue (b.LastBuildOutput.ContainsText (Path.Combine (proj.TargetFrameworkVersion, "mono.android.jar")), proj.TargetFrameworkVersion + "/mono.android.jar should be used."); + Assert.IsFalse (b.LastBuildOutput.ContainsText ("Duplicate zip entry"), "Should not get warning about [META-INF/MANIFEST.MF]"); } } @@ -437,6 +438,7 @@ public override void OnCreate() }" }); using (var b = CreateApkBuilder ("temp/CustomApplicationClassAndMultiDex")) { Assert.IsTrue (b.Build (proj), "Build should have succeeded."); + Assert.IsFalse (b.LastBuildOutput.ContainsText ("Duplicate zip entry"), "Should not get warning about [META-INF/MANIFEST.MF]"); } } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs index 1c1c91c3f72..36f80ac407e 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs @@ -252,6 +252,9 @@ protected bool BuildInternal (string projectOrSolution, string target, string [] psi.EnvironmentVariables [kvp.Key] = kvp.Value; } } + //NOTE: fix for Jenkins, see https://github.com/xamarin/xamarin-android/pull/1049#issuecomment-347625456 + psi.EnvironmentVariables ["ghprbPullLongDescription"] = ""; + psi.Arguments = args.ToString (); psi.CreateNoWindow = true; diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 774b651d18c..e42437ce995 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -248,6 +248,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. <_AndroidLibrayProjectIntermediatePath Condition=" '$(_AndroidLibrayProjectIntermediatePath)' == '' And '$(UseShortFileNames)' == 'True' ">$(IntermediateOutputPath)lp\ <_AndroidLibrayProjectIntermediatePath Condition=" '$(_AndroidLibrayProjectIntermediatePath)' == '' ">$(IntermediateOutputPath)__library_projects__\ <_AndroidLibrayProjectAssemblyMapFile>$(_AndroidLibrayProjectIntermediatePath)map.cache + <_AndroidProguardInputJarFilter>(!META-INF/MANIFEST.MF) $(EnableProguard) @@ -2153,6 +2154,7 @@ because xbuild doesn't support framework reference assemblies. PrintSeedsOutput="$(IntermediateOutputPath)proguard\seeds.txt" PrintUsageOutput="$(IntermediateOutputPath)proguard\usage.txt" PrintMappingOutput="$(IntermediateOutputPath)proguard\mapping.txt" + ProguardInputJarFilter="$(_AndroidProguardInputJarFilter)" />