diff --git a/Documentation/guides/building-apps/build-properties.md b/Documentation/guides/building-apps/build-properties.md index 31321ae15c6..031d5002750 100644 --- a/Documentation/guides/building-apps/build-properties.md +++ b/Documentation/guides/building-apps/build-properties.md @@ -806,6 +806,17 @@ with build environments that have FIPS compliance enforced. Added in Xamarin.Android 10.1. +## AndroidProguardMappingFile + +Specifies the `-printmapping` proguard rule for `r8`. This will +mean the `mapping.txt` file will be produced in the `$(OutputPath)` +folder. This file can then be used when uploading packages to the +Google Play Store. + +Default value is `$(OutputPath)mapping.txt` + +Added in Xamarin.Android 11.2 + ## AndroidR8IgnoreWarnings Specifies diff --git a/Documentation/release-notes/5304.md b/Documentation/release-notes/5304.md new file mode 100644 index 00000000000..c646302b1a4 --- /dev/null +++ b/Documentation/release-notes/5304.md @@ -0,0 +1,9 @@ +### Build and deployment performance + + * [GitHub PR 5304](https://github.com/xamarin/xamarin-android/pull/5304): + Add support for producing a proguard `mapping.txt` file to the + build system. This file can be used by users to remove this warning + + "This App Bundle contains Java/Kotlin code, which might be obfuscated." + + when uploading packages to the Google Play Store. \ No newline at end of file diff --git a/src/Xamarin.Android.Build.Tasks/Resources/proguard_xamarin.cfg b/src/Xamarin.Android.Build.Tasks/Resources/proguard_xamarin.cfg index 914ef686ac2..d74e057069a 100644 --- a/src/Xamarin.Android.Build.Tasks/Resources/proguard_xamarin.cfg +++ b/src/Xamarin.Android.Build.Tasks/Resources/proguard_xamarin.cfg @@ -2,6 +2,10 @@ -dontobfuscate +# required for publishing proguard mapping file +-keepattributes SourceFile +-keepattributes LineNumberTable + -keep class android.support.multidex.MultiDexApplication { (); } -keep class com.xamarin.java_interop.** { *; (); } -keep class mono.MonoRuntimeProvider* { *; (...); } diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Proguard.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Proguard.cs index 667bb08dba9..5f1399fd153 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Proguard.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Proguard.cs @@ -48,14 +48,15 @@ public class Proguard : AndroidToolTask public string ProguardGeneratedReferenceConfiguration { get; set; } public string ProguardGeneratedApplicationConfiguration { get; set; } public string ProguardCommonXamarinConfiguration { get; set; } + public string ProguardMappingFileOutput { get; set; } [Required] public string [] ProguardConfigurationFiles { get; set; } public ITaskItem[] JavaLibrariesToEmbed { get; set; } - + public ITaskItem[] JavaLibrariesToReference { get; set; } - + public bool UseProguard { get; set; } public string JavaOptions { get; set; } @@ -92,11 +93,11 @@ protected override string GenerateCommandLineCommands () // Add the JavaOptions if they are not null // These could be any of the additional options if (!string.IsNullOrEmpty (JavaOptions)) { - cmd.AppendSwitch (JavaOptions); + cmd.AppendSwitch (JavaOptions); } // Add the specific -XmxN to override the default heap size for the JVM - // N can be in the form of Nm or NGB (e.g 100m or 1GB ) + // N can be in the form of Nm or NGB (e.g 100m or 1GB ) cmd.AppendSwitchIfNotNull ("-Xmx", JavaMaximumHeapSize); cmd.AppendSwitchIfNotNull ("-jar ", Path.Combine (ProguardJarPath)); @@ -118,9 +119,12 @@ protected override string GenerateCommandLineCommands () } if (!string.IsNullOrWhiteSpace (ProguardCommonXamarinConfiguration)) - using (var xamcfg = File.Create (ProguardCommonXamarinConfiguration)) - GetType ().Assembly.GetManifestResourceStream ("proguard_xamarin.cfg").CopyTo (xamcfg); - + using (var xamcfg = File.CreateText (ProguardCommonXamarinConfiguration)) { + GetType ().Assembly.GetManifestResourceStream ("proguard_xamarin.cfg").CopyTo (xamcfg.BaseStream); + if (!string.IsNullOrEmpty (ProguardMappingFileOutput)) + xamcfg.WriteLine ($"-printmapping {Path.GetFullPath (ProguardMappingFileOutput)}"); + } + var enclosingChar = OS.IsWindows ? "\"" : string.Empty; foreach (var file in ProguardConfigurationFiles) { diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/R8.cs b/src/Xamarin.Android.Build.Tasks/Tasks/R8.cs index 244eba6fec6..02cee3f22e9 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/R8.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/R8.cs @@ -29,6 +29,7 @@ public class R8 : D8 public string ProguardGeneratedReferenceConfiguration { get; set; } public string ProguardGeneratedApplicationConfiguration { get; set; } public string ProguardCommonXamarinConfiguration { get; set; } + public string ProguardMappingFileOutput { get; set; } public string [] ProguardConfigurationFiles { get; set; } protected override string MainClass => "com.android.tools.r8.R8"; @@ -99,6 +100,8 @@ protected override CommandLineBuilder GetCommandLineBuilder () if (IgnoreWarnings) { xamcfg.WriteLine ("-ignorewarnings"); } + if (!string.IsNullOrEmpty (ProguardMappingFileOutput)) + xamcfg.WriteLine ($"-printmapping {Path.GetFullPath (ProguardMappingFileOutput)}"); } } } else { @@ -115,6 +118,8 @@ protected override CommandLineBuilder GetCommandLineBuilder () if (IgnoreWarnings) { lines.Add ("-ignorewarnings"); } + if (!string.IsNullOrEmpty (ProguardMappingFileOutput)) + lines.Add ($"-printmapping {Path.GetFullPath (ProguardMappingFileOutput)}"); File.WriteAllLines (temp, lines); tempFiles.Add (temp); cmd.AppendSwitchIfNotNull ("--pg-conf ", temp); @@ -131,5 +136,5 @@ protected override CommandLineBuilder GetCommandLineBuilder () return cmd; } } - + } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs index fedebe477d5..5a5486c38cd 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs @@ -48,6 +48,21 @@ public void CheckManagedSymbolsArchive (bool isRelease, bool monoSymbolArchive, } } + [Test] + public void CheckProguardMappingFileExists () + { + var proj = new XamarinAndroidApplicationProject { + IsRelease = true, + }; + proj.SetProperty (proj.ReleaseProperties, KnownProperties.AndroidDexTool, "d8"); + proj.SetProperty (proj.ReleaseProperties, KnownProperties.AndroidLinkTool, "r8"); + using (var b = CreateApkBuilder ()) { + Assert.IsTrue (b.Build (proj), "build should have succeeded."); + string mappingFile = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, "mapping.txt"); + FileAssert.Exists (mappingFile, $"'{mappingFile}' should have been generated."); + } + } + [Test] public void CheckIncludedAssemblies () { diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index edbdc49bdd0..40a63abdab0 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -275,6 +275,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved. proguard r8 True + $(OutputPath)mapping.txt True False True diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.D8.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.D8.targets index bf0d3310dc3..f23db33f84a 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.D8.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.D8.targets @@ -67,6 +67,7 @@ Copyright (C) 2018 Xamarin. All rights reserved. ProguardCommonXamarinConfiguration="$(IntermediateOutputPath)proguard\proguard_xamarin.cfg" ProguardGeneratedReferenceConfiguration="$(_ProguardProjectConfiguration)" ProguardGeneratedApplicationConfiguration="$(IntermediateOutputPath)proguard\proguard_project_primary.cfg" + ProguardMappingFileOutput="$(AndroidProguardMappingFile)" ProguardConfigurationFiles="@(_ProguardConfiguration)" EnableShrinking="$(_R8EnableShrinking)" EnableMultiDex="$(AndroidEnableMultiDex)" @@ -96,6 +97,7 @@ Copyright (C) 2018 Xamarin. All rights reserved. + diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.DX.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.DX.targets index 71195956a97..0ff87f32115 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.DX.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.DX.targets @@ -26,7 +26,7 @@ Copyright (C) 2018 Xamarin. All rights reserved. <_JarsToProguard Include="@(_JavaLibrariesToCompile)" /> - + - +