Skip to content

Commit 59aff45

Browse files
jonpryoratsushieno
authored andcommitted
[Xamarin.Android.Build.Tasks] Use GPL'd ProGuard (#386)
**Background**: many Android SDK features rely on [ProGuard][0], a Java bytecode manipulation library. Some of these features include linking (shrinking) bytecode and [multidex][1]. Xamarin.Android has historically relied on the version of ProGuard bundled with the Android SDK, which is how the `<Proguard/>` task and `@(ProguardConfiguration)` build actions work. Unfortunately, the version of ProGuard bundled with the Android SDK is, at this point, *ancient* (ProGuard v4.7; current version is v5.3), and (more importantly) ProGuard v4.7 doesn't support JDK 1.8 bytecode. Meaning if the end-developer references a Java library targeting JDK 1.8 -- e.g. the Android Support Library v25 -- then the version of ProGuard bundled with the Android SDK *cannot process that library*. This in turn means that the `<Proguard/>` task and `@(ProguardConfiguration)` build actions don't work/are useless. Native Java development "works around" this problem by using Gradle as the build system, and Java projects are configured to download and install a newer version of ProGuard via Gradle. Xamarin.Android projects do not use Gradle, nor will they. (At least not in the foreseeable future.) **Solution**: We have communicated with Eric Lafortune, maintainer of ProGuard, about distributing a newer ProGuard with Xamarin.Android. He replied: > From a licensing point of view, you shouldn't need an exception to > the GPL in many practical configurations: > > * if you indeed run ProGuard in a separate JVM The `<Proguard/>` task is a [`ToolTask`][2], which operates by creating a new process to invoke the specified tool. We thus are *already* using ProGuard within a "separate JVM", and no architectural change is required to comply with ProGuard's licensing without altering Xamarin.Android's licensing. The current ProGuard sources (v5.3.2) have been imported into the [xamarin/proguard][3] module, and we will be using the `xamarin/proguard` module as a git submodule for build purposes. [0]: https://www.guardsquare.com/en/proguard [1]: https://developer.android.com/studio/build/multidex.html [2]: https://msdn.microsoft.com/en-us/library/microsoft.build.utilities.tooltask.aspx [3]: http://github.com/xamarin/proguard/
1 parent 95c3eb3 commit 59aff45

File tree

8 files changed

+87
-1
lines changed

8 files changed

+87
-1
lines changed

.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@
3232
[submodule "external/linker"]
3333
path = external/linker
3434
url = https://github.com/mono/linker.git
35+
[submodule "external/proguard"]
36+
path = external/proguard
37+
url = https://github.com/xamarin/proguard.git
38+
branch = master

Configuration.props

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<OpenTKSourceDirectory>$(MSBuildThisFileDirectory)external\opentk</OpenTKSourceDirectory>
5050
<LibZipSourceDirectory Condition=" '$(LibZipSourceDirectory)' == '' ">$(MSBuildThisFileDirectory)external\libzip</LibZipSourceDirectory>
5151
<LibZipSharpSourceDirectory Condition=" '$(LibZipSharpSourceDirectory)' == '' ">$(MSBuildThisFileDirectory)external\LibZipSharp</LibZipSharpSourceDirectory>
52+
<ProGuardSourceDirectory Condition=" '$(ProGuardSourceDirectory)' == '' ">$(MSBuildThisFileDirectory)external\proguard</ProGuardSourceDirectory>
5253
<SqliteSourceDirectory Condition=" '$(SqliteSourceDirectory)' == '' ">$(MSBuildThisFileDirectory)external\sqlite</SqliteSourceDirectory>
5354
<XamarinAndroidSourcePath>$(MSBuildThisFileDirectory)</XamarinAndroidSourcePath>
5455
<AllSupported32BitTargetAndroidAbis>armeabi;armeabi-v7a;x86</AllSupported32BitTargetAndroidAbis>
@@ -73,6 +74,7 @@
7374
<OpenTKSourceFullPath>$([System.IO.Path]::GetFullPath ('$(OpenTKSourceDirectory)'))</OpenTKSourceFullPath>
7475
<LibZipSourceFullPath>$([System.IO.Path]::GetFullPath ('$(LibZipSourceDirectory)'))</LibZipSourceFullPath>
7576
<LibZipSharpSourceFullPath>$([System.IO.Path]::GetFullPath ('$(LibZipSharpSourceDirectory)'))</LibZipSharpSourceFullPath>
77+
<ProGuardSourceFullPath>$([System.IO.Path]::GetFullPath ('$(ProGuardSourceDirectory)'))</ProGuardSourceFullPath>
7678
</PropertyGroup>
7779
<PropertyGroup>
7880
<AdbToolPath Condition=" '$(AdbToolPath)' == '' ">$(AndroidSdkFullPath)\platform-tools</AdbToolPath>

Xamarin.Android.sln

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.Cecil.Mdb",
9999
EndProject
100100
Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "dependencies", "build-tools\dependencies\dependencies.mdproj", "{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD}"
101101
EndProject
102+
Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "proguard", "src\proguard\proguard.mdproj", "{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}"
103+
EndProject
102104
Global
103105
GlobalSection(SolutionConfigurationPlatforms) = preSolution
104106
Debug|AnyCPU = Debug|AnyCPU
@@ -457,6 +459,14 @@ Global
457459
{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD}.XAIntegrationDebug|AnyCPU.Build.0 = Debug|Any CPU
458460
{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD}.XAIntegrationRelease|AnyCPU.ActiveCfg = Debug|Any CPU
459461
{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD}.XAIntegrationRelease|AnyCPU.Build.0 = Debug|Any CPU
462+
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
463+
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}.Debug|AnyCPU.Build.0 = Debug|Any CPU
464+
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}.Release|AnyCPU.ActiveCfg = Release|Any CPU
465+
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}.Release|AnyCPU.Build.0 = Release|Any CPU
466+
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}.XAIntegrationDebug|AnyCPU.ActiveCfg = Debug|Any CPU
467+
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}.XAIntegrationDebug|AnyCPU.Build.0 = Debug|Any CPU
468+
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}.XAIntegrationRelease|AnyCPU.ActiveCfg = Debug|Any CPU
469+
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}.XAIntegrationRelease|AnyCPU.Build.0 = Debug|Any CPU
460470
EndGlobalSection
461471
GlobalSection(NestedProjects) = preSolution
462472
{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
@@ -504,6 +514,7 @@ Global
504514
{C0487169-8F81-497F-919E-EB42B1D0243F} = {864062D3-A415-4A6F-9324-5820237BA058}
505515
{C876DA71-8573-4CEF-9149-716D72455ED4} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
506516
{C845ECC0-2ED3-498E-8EA8-02EF7AC6E9AD} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
517+
{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
507518
EndGlobalSection
508519
GlobalSection(MonoDevelopProperties) = preSolution
509520
Policies = $0

external/proguard

Submodule proguard added at 905836d

src/Xamarin.Android.Build.Tasks/Xamarin.Android.Build.Tasks.csproj

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,15 @@
633633
<Name>Xamarin.Android.Tools.BootstrapTasks</Name>
634634
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
635635
</ProjectReference>
636+
<!--
637+
*Logically* needs to be built first because executing the <Proguard/>
638+
task will require the outputs of `proguard.mdproj`.
639+
-->
640+
<ProjectReference Include="..\proguard\proguard.mdproj">
641+
<Project>{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}</Project>
642+
<Name>proguard</Name>
643+
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
644+
</ProjectReference>
636645
<ProjectReference Include="$(LibZipSharpSourceFullPath)\libZipSharp.csproj">
637646
<Project>{E248B2CA-303B-4645-ADDC-9D4459D550FD}</Project>
638647
<Name>libZipSharp</Name>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ because xbuild doesn't support framework reference assemblies.
756756
/>
757757
</CreateProperty>
758758

759-
<CreateProperty Value="$(AndroidSdkDirectory)\tools\proguard\">
759+
<CreateProperty Value="$(MonoAndroidToolsDirectory)\proguard\">
760760
<Output TaskParameter="Value" PropertyName="ProguardToolPath"
761761
Condition="'$(ProguardToolPath)' == ''"
762762
/>

src/proguard/proguard.mdproj

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<PropertyGroup>
3+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5+
<ItemType>GenericProject</ItemType>
6+
<ProjectGuid>{4B9D96BB-95AB-44E8-9F87-13B12C8BCED1}</ProjectGuid>
7+
<OutputPath>..\..\bin\$(Configuration)\lib\mandroid\proguard</OutputPath>
8+
</PropertyGroup>
9+
<Import Project="..\..\Configuration.props" />
10+
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
11+
</PropertyGroup>
12+
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
13+
</PropertyGroup>
14+
<Import Project="$(MSBuildBinPath)\Microsoft.Common.targets" />
15+
<PropertyGroup>
16+
<BuildDependsOn>
17+
ResolveReferences;
18+
_BuildProGuard
19+
</BuildDependsOn>
20+
</PropertyGroup>
21+
<Import Project="proguard.targets" />
22+
</Project>

src/proguard/proguard.targets

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<Target Name="_BuildProGuard">
3+
<Exec
4+
Command="$(AntDirectory)\bin\ant -verbose -f buildscripts\build.xml proguard"
5+
WorkingDirectory="$(ProGuardSourceFullPath)"
6+
/>
7+
<MakeDir Directories="$(OutputPath)" />
8+
<Copy
9+
SourceFiles="..\..\external\proguard\lib\proguard.jar"
10+
DestinationFiles="$(OutputPath)\lib\proguard.jar"
11+
/>
12+
<Copy
13+
SourceFiles="..\..\external\proguard\bin\proguard.bat"
14+
DestinationFiles="$(OutputPath)\bin\proguard.bat"
15+
/>
16+
<Copy
17+
SourceFiles="..\..\external\proguard\bin\proguard.sh"
18+
DestinationFiles="$(OutputPath)\bin\proguard.sh"
19+
/>
20+
<Copy
21+
SourceFiles="..\..\external\proguard\docs\license.html"
22+
DestinationFiles="$(OutputPath)\license.html"
23+
/>
24+
</Target>
25+
<Target Name="_CleanProGuard"
26+
AfterTargets="Clean">
27+
<Delete Files="$(OutputPath)\license.html" />
28+
<Delete Files="$(OutputPath)\lib\proguard.jar" />
29+
<Delete Files="$(OutputPath)\bin\proguard.sh" />
30+
<Delete Files="$(OutputPath)\bin\proguard.bat" />
31+
<Exec
32+
Command="$(AntDirectory)\bin\ant -f buildscripts\build.xml clean"
33+
WorkingDirectory="$(ProGuardSourceFullPath)"
34+
/>
35+
</Target>
36+
</Project>
37+

0 commit comments

Comments
 (0)