Skip to content

Commit 2dab2bc

Browse files
authored
[Xamarin.Android.Build.Tasks] Add support for Proguard mapping.txt file. (#5304)
Fixes: #5186 When uploading a package to the Google Play Store users are seeing the following warning: This App Bundle contains Java/Kotlin code, which might be obfuscated. To fix this users need to provide a `mapping.txt` file which contains the Java class mappings from their plain versions to the ones which are obfuscated. By default we do not obfuscate the java code but the warning still appears. To fix this issue we have a new `$(AndroidProguardMappingFile)` MSBuild property which defaults to `$(OutputPath)mapping.txt`. This file will be produced as part of the build process. In order for this mapping file to be generated, the following lines needed to be added to `proguard_xamarin.cfg`: -keepattributes SourceFile -keepattributes LineNumberTable
1 parent 2c07645 commit 2dab2bc

File tree

9 files changed

+63
-10
lines changed

9 files changed

+63
-10
lines changed

Documentation/guides/building-apps/build-properties.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,17 @@ with build environments that have FIPS compliance enforced.
806806

807807
Added in Xamarin.Android 10.1.
808808

809+
## AndroidProguardMappingFile
810+
811+
Specifies the `-printmapping` proguard rule for `r8`. This will
812+
mean the `mapping.txt` file will be produced in the `$(OutputPath)`
813+
folder. This file can then be used when uploading packages to the
814+
Google Play Store.
815+
816+
Default value is `$(OutputPath)mapping.txt`
817+
818+
Added in Xamarin.Android 11.2
819+
809820
## AndroidR8IgnoreWarnings
810821

811822
Specifies
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
### Build and deployment performance
2+
3+
* [GitHub PR 5304](https://github.com/xamarin/xamarin-android/pull/5304):
4+
Add support for producing a proguard `mapping.txt` file to the
5+
build system. This file can be used by users to remove this warning
6+
7+
"This App Bundle contains Java/Kotlin code, which might be obfuscated."
8+
9+
when uploading packages to the Google Play Store.

src/Xamarin.Android.Build.Tasks/Resources/proguard_xamarin.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
-dontobfuscate
44

5+
# required for publishing proguard mapping file
6+
-keepattributes SourceFile
7+
-keepattributes LineNumberTable
8+
59
-keep class android.support.multidex.MultiDexApplication { <init>(); }
610
-keep class com.xamarin.java_interop.** { *; <init>(); }
711
-keep class mono.MonoRuntimeProvider* { *; <init>(...); }

src/Xamarin.Android.Build.Tasks/Tasks/Proguard.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,15 @@ public class Proguard : AndroidToolTask
4848
public string ProguardGeneratedReferenceConfiguration { get; set; }
4949
public string ProguardGeneratedApplicationConfiguration { get; set; }
5050
public string ProguardCommonXamarinConfiguration { get; set; }
51+
public string ProguardMappingFileOutput { get; set; }
5152

5253
[Required]
5354
public string [] ProguardConfigurationFiles { get; set; }
5455

5556
public ITaskItem[] JavaLibrariesToEmbed { get; set; }
56-
57+
5758
public ITaskItem[] JavaLibrariesToReference { get; set; }
58-
59+
5960
public bool UseProguard { get; set; }
6061

6162
public string JavaOptions { get; set; }
@@ -92,11 +93,11 @@ protected override string GenerateCommandLineCommands ()
9293
// Add the JavaOptions if they are not null
9394
// These could be any of the additional options
9495
if (!string.IsNullOrEmpty (JavaOptions)) {
95-
cmd.AppendSwitch (JavaOptions);
96+
cmd.AppendSwitch (JavaOptions);
9697
}
9798

9899
// Add the specific -XmxN to override the default heap size for the JVM
99-
// N can be in the form of Nm or NGB (e.g 100m or 1GB )
100+
// N can be in the form of Nm or NGB (e.g 100m or 1GB )
100101
cmd.AppendSwitchIfNotNull ("-Xmx", JavaMaximumHeapSize);
101102

102103
cmd.AppendSwitchIfNotNull ("-jar ", Path.Combine (ProguardJarPath));
@@ -118,9 +119,12 @@ protected override string GenerateCommandLineCommands ()
118119
}
119120

120121
if (!string.IsNullOrWhiteSpace (ProguardCommonXamarinConfiguration))
121-
using (var xamcfg = File.Create (ProguardCommonXamarinConfiguration))
122-
GetType ().Assembly.GetManifestResourceStream ("proguard_xamarin.cfg").CopyTo (xamcfg);
123-
122+
using (var xamcfg = File.CreateText (ProguardCommonXamarinConfiguration)) {
123+
GetType ().Assembly.GetManifestResourceStream ("proguard_xamarin.cfg").CopyTo (xamcfg.BaseStream);
124+
if (!string.IsNullOrEmpty (ProguardMappingFileOutput))
125+
xamcfg.WriteLine ($"-printmapping {Path.GetFullPath (ProguardMappingFileOutput)}");
126+
}
127+
124128
var enclosingChar = OS.IsWindows ? "\"" : string.Empty;
125129

126130
foreach (var file in ProguardConfigurationFiles) {

src/Xamarin.Android.Build.Tasks/Tasks/R8.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class R8 : D8
2929
public string ProguardGeneratedReferenceConfiguration { get; set; }
3030
public string ProguardGeneratedApplicationConfiguration { get; set; }
3131
public string ProguardCommonXamarinConfiguration { get; set; }
32+
public string ProguardMappingFileOutput { get; set; }
3233
public string [] ProguardConfigurationFiles { get; set; }
3334

3435
protected override string MainClass => "com.android.tools.r8.R8";
@@ -99,6 +100,8 @@ protected override CommandLineBuilder GetCommandLineBuilder ()
99100
if (IgnoreWarnings) {
100101
xamcfg.WriteLine ("-ignorewarnings");
101102
}
103+
if (!string.IsNullOrEmpty (ProguardMappingFileOutput))
104+
xamcfg.WriteLine ($"-printmapping {Path.GetFullPath (ProguardMappingFileOutput)}");
102105
}
103106
}
104107
} else {
@@ -115,6 +118,8 @@ protected override CommandLineBuilder GetCommandLineBuilder ()
115118
if (IgnoreWarnings) {
116119
lines.Add ("-ignorewarnings");
117120
}
121+
if (!string.IsNullOrEmpty (ProguardMappingFileOutput))
122+
lines.Add ($"-printmapping {Path.GetFullPath (ProguardMappingFileOutput)}");
118123
File.WriteAllLines (temp, lines);
119124
tempFiles.Add (temp);
120125
cmd.AppendSwitchIfNotNull ("--pg-conf ", temp);
@@ -131,5 +136,5 @@ protected override CommandLineBuilder GetCommandLineBuilder ()
131136
return cmd;
132137
}
133138
}
134-
139+
135140
}

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/PackagingTest.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,21 @@ public void CheckManagedSymbolsArchive (bool isRelease, bool monoSymbolArchive,
4848
}
4949
}
5050

51+
[Test]
52+
public void CheckProguardMappingFileExists ()
53+
{
54+
var proj = new XamarinAndroidApplicationProject {
55+
IsRelease = true,
56+
};
57+
proj.SetProperty (proj.ReleaseProperties, KnownProperties.AndroidDexTool, "d8");
58+
proj.SetProperty (proj.ReleaseProperties, KnownProperties.AndroidLinkTool, "r8");
59+
using (var b = CreateApkBuilder ()) {
60+
Assert.IsTrue (b.Build (proj), "build should have succeeded.");
61+
string mappingFile = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath, "mapping.txt");
62+
FileAssert.Exists (mappingFile, $"'{mappingFile}' should have been generated.");
63+
}
64+
}
65+
5166
[Test]
5267
public void CheckIncludedAssemblies ()
5368
{

src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
275275
<AndroidLinkTool Condition=" '$(AndroidLinkTool)' == '' And '$(AndroidEnableProguard)' == 'True' ">proguard</AndroidLinkTool>
276276
<AndroidLinkTool Condition=" '$(AndroidLinkTool)' == 'proguard' And '$(AndroidEnableDesugar)' == 'True' ">r8</AndroidLinkTool>
277277
<AndroidEnableProguard Condition=" '$(AndroidLinkTool)' != '' ">True</AndroidEnableProguard>
278+
<AndroidProguardMappingFile Condition=" '$(AndroidProguardMappingFile)' == '' ">$(OutputPath)mapping.txt</AndroidProguardMappingFile>
278279
<AndroidEnableDesugar Condition=" '$(AndroidEnableDesugar)' == '' And ('$(AndroidDexTool)' == 'd8' Or '$(AndroidLinkTool)' == 'r8') ">True</AndroidEnableDesugar>
279280
<AndroidEnableDesugar Condition=" '$(AndroidEnableDesugar)' == '' ">False</AndroidEnableDesugar>
280281
<AndroidR8IgnoreWarnings Condition=" '$(AndroidR8IgnoreWarnings)' == '' ">True</AndroidR8IgnoreWarnings>

src/Xamarin.Android.Build.Tasks/Xamarin.Android.D8.targets

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ Copyright (C) 2018 Xamarin. All rights reserved.
6767
ProguardCommonXamarinConfiguration="$(IntermediateOutputPath)proguard\proguard_xamarin.cfg"
6868
ProguardGeneratedReferenceConfiguration="$(_ProguardProjectConfiguration)"
6969
ProguardGeneratedApplicationConfiguration="$(IntermediateOutputPath)proguard\proguard_project_primary.cfg"
70+
ProguardMappingFileOutput="$(AndroidProguardMappingFile)"
7071
ProguardConfigurationFiles="@(_ProguardConfiguration)"
7172
EnableShrinking="$(_R8EnableShrinking)"
7273
EnableMultiDex="$(AndroidEnableMultiDex)"
@@ -96,6 +97,7 @@ Copyright (C) 2018 Xamarin. All rights reserved.
9697
<Touch Files="$(_AndroidStampDirectory)_CompileToDalvik.stamp" AlwaysCreate="true" />
9798
<ItemGroup>
9899
<FileWrites Include="$(_AndroidIntermediateDexOutputDirectory)*.dex" />
100+
<FileWrites Include="$(AndroidProguardMappingFile)" />
99101
</ItemGroup>
100102

101103
</Target>

src/Xamarin.Android.Build.Tasks/Xamarin.Android.DX.targets

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Copyright (C) 2018 Xamarin. All rights reserved.
2626
<ItemGroup>
2727
<_JarsToProguard Include="@(_JavaLibrariesToCompile)" />
2828
</ItemGroup>
29-
29+
3030
<MakeDir Directories="$(IntermediateOutputPath)proguard" />
3131

3232
<Proguard
@@ -42,6 +42,7 @@ Copyright (C) 2018 Xamarin. All rights reserved.
4242
ProguardCommonXamarinConfiguration="$(IntermediateOutputPath)proguard\proguard_xamarin.cfg"
4343
ProguardGeneratedReferenceConfiguration="$(_ProguardProjectConfiguration)"
4444
ProguardGeneratedApplicationConfiguration="$(IntermediateOutputPath)proguard\proguard_project_primary.cfg"
45+
ProguardMappingFileOutput="$(AndroidProguardMappingFile)"
4546
ProguardConfigurationFiles="@(_ProguardConfiguration)"
4647
JavaLibrariesToEmbed="@(_JarsToProguard);@(_InstantRunJavaReference)"
4748
JavaLibrariesToReference="@(AndroidExternalJavaLibrary)"
@@ -79,7 +80,7 @@ Copyright (C) 2018 Xamarin. All rights reserved.
7980
<Delete Files="@(_DexesToDelete)" />
8081

8182
<!-- Compile java code to dalvik -->
82-
<CompileToDalvik
83+
<CompileToDalvik
8384
DxJarPath="$(DxJarPath)"
8485
DxExtraArguments="$(DxExtraArguments)"
8586
JavaToolPath="$(JavaToolPath)"
@@ -98,6 +99,7 @@ Copyright (C) 2018 Xamarin. All rights reserved.
9899
<Touch Files="$(_AndroidStampDirectory)_CompileToDalvik.stamp" AlwaysCreate="true" />
99100
<ItemGroup>
100101
<FileWrites Include="$(_AndroidIntermediateDexOutputDirectory)*.dex" />
102+
<FileWrites Include="$(AndroidProguardMappingFile)" />
101103
</ItemGroup>
102104

103105
</Target>

0 commit comments

Comments
 (0)