[msbuild] support custom proguard via ProguardToolPath for multidex etc. (#267)
We had ProguardToolPath and it could be used for custom proguard tools, which should be useful if we want to support Java8 based libraries which doesn't work with the one in Android SDK. In theory. In fact, it was not sufficient because proguard is also used by multidex. To support multidex, we have to generate correct mainDexClasses rules that should depend on Android SDK path, not proguard. To support custom proguard, we need PROGUARD_HOME environment variable in mainDexClasses(.bat). That actually uncovered another issue we had: we were using ToolTask.EnvironmentOverride which is [Obsolete] and converts every entry to lowercase, which can work on Windows but not elsewhere i.e. even if we had PROGUARD_HOME, it became proguard_home(!) Therefore we use ToolTask.EnvironmentVariables instead from now on. Due to xbuild property parser issue, it differentiates MSBuild on Windows and xbuild elsewhere to give some additional env. variables.
This commit is contained in:
Родитель
eb45485f10
Коммит
a967b24cf3
|
@ -17,6 +17,11 @@ namespace Xamarin.Android.Tasks
|
|||
[Required]
|
||||
public string ClassesOutputDirectory { get; set; }
|
||||
|
||||
[Required]
|
||||
public string ProguardHome { get; set; }
|
||||
|
||||
public string MSBuildRuntimeType { get; set; }
|
||||
|
||||
[Required]
|
||||
public ITaskItem[] JavaLibraries { get; set; }
|
||||
|
||||
|
@ -32,6 +37,8 @@ namespace Xamarin.Android.Tasks
|
|||
Log.LogDebugTaskItems (" CustomMainDexListFiles:", CustomMainDexListFiles);
|
||||
Log.LogDebugMessage (" ToolExe: {0}", ToolExe);
|
||||
Log.LogDebugMessage (" ToolPath: {0}", ToolPath);
|
||||
Log.LogDebugMessage (" MSBuildRuntimeType: {0}", MSBuildRuntimeType);
|
||||
Log.LogDebugMessage (" ProguardHome: {0}", ProguardHome);
|
||||
|
||||
if (CustomMainDexListFiles != null && CustomMainDexListFiles.Any ()) {
|
||||
var content = string.Concat (CustomMainDexListFiles.Select (i => File.ReadAllText (i.ItemSpec)));
|
||||
|
@ -39,6 +46,13 @@ namespace Xamarin.Android.Tasks
|
|||
return true;
|
||||
}
|
||||
|
||||
// Windows seems to need special care, needs JAVA_TOOL_OPTIONS.
|
||||
// On the other hand, xbuild has a bug and fails to parse '=' in the value, so we skip JAVA_TOOL_OPTIONS on Mono runtime.
|
||||
EnvironmentVariables =
|
||||
string.IsNullOrEmpty (MSBuildRuntimeType) || MSBuildRuntimeType == "Mono" ?
|
||||
new string [] { "PROGUARD_HOME=" + ProguardHome } :
|
||||
new string [] { "JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8", "PROGUARD_HOME=" + ProguardHome };
|
||||
|
||||
return base.Execute ();
|
||||
}
|
||||
|
||||
|
@ -69,17 +83,6 @@ namespace Xamarin.Android.Tasks
|
|||
{
|
||||
return Path.Combine (ToolPath, ToolExe);
|
||||
}
|
||||
|
||||
// Windows seems to need special care.
|
||||
protected override StringDictionary EnvironmentOverride {
|
||||
get {
|
||||
var sd = base.EnvironmentOverride ?? new StringDictionary ();
|
||||
var opts = sd.ContainsKey ("JAVA_TOOL_OPTIONS") ? sd ["JAVA_TOOL_OPTIONS"] : null;
|
||||
opts += " -Dfile.encoding=UTF8";
|
||||
sd ["JAVA_TOOL_OPTIONS"] = opts;
|
||||
return sd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@ namespace Xamarin.Android.Tasks
|
|||
[Required]
|
||||
public string JavaPlatformJackPath { get; set; }
|
||||
|
||||
[Required]
|
||||
public string AndroidSdkDirectory { get; set; }
|
||||
|
||||
[Required]
|
||||
public string [] InputJackFiles { get; set; }
|
||||
|
||||
|
@ -112,7 +115,7 @@ namespace Xamarin.Android.Tasks
|
|||
// skip invalid lines
|
||||
}
|
||||
var configs = ProguardConfigurationFiles
|
||||
.Replace ("{sdk.dir}", Path.GetDirectoryName (Path.GetDirectoryName (ProguardJarPath)) + Path.DirectorySeparatorChar)
|
||||
.Replace ("{sdk.dir}", AndroidSdkDirectory + Path.DirectorySeparatorChar)
|
||||
.Replace ("{intermediate.common.xamarin}", ProguardCommonXamarinConfiguration)
|
||||
.Replace ("{intermediate.references}", ProguardGeneratedReferenceConfiguration)
|
||||
.Replace ("{intermediate.application}", ProguardGeneratedApplicationConfiguration)
|
||||
|
|
|
@ -22,11 +22,18 @@ namespace Xamarin.Android.Tasks
|
|||
{
|
||||
public string ProguardJarPath { get; set; }
|
||||
|
||||
public string ProguardToolPath { get; set; }
|
||||
|
||||
public string JavaToolPath { get; set; }
|
||||
|
||||
public string MSBuildRuntimeType { get; set; }
|
||||
|
||||
[Required]
|
||||
public string JavaPlatformJarPath { get; set; }
|
||||
|
||||
[Required]
|
||||
public string AndroidSdkDirectory { get; set; }
|
||||
|
||||
[Required]
|
||||
public string ClassesOutputDirectory { get; set; }
|
||||
|
||||
|
@ -79,6 +86,8 @@ namespace Xamarin.Android.Tasks
|
|||
public override bool Execute ()
|
||||
{
|
||||
Log.LogDebugMessage ("Proguard");
|
||||
Log.LogDebugMessage (" AndroidSdkDirectory: {0}", AndroidSdkDirectory);
|
||||
Log.LogDebugMessage (" MSBuildRuntimeType: {0}", MSBuildRuntimeType);
|
||||
Log.LogDebugMessage (" JavaPlatformJarPath: {0}", JavaPlatformJarPath);
|
||||
Log.LogDebugMessage (" ClassesOutputDirectory: {0}", ClassesOutputDirectory);
|
||||
Log.LogDebugMessage (" AcwMapFile: {0}", AcwMapFile);
|
||||
|
@ -97,6 +106,13 @@ namespace Xamarin.Android.Tasks
|
|||
Log.LogDebugMessage (" PrintSeedsOutput: {0}", PrintSeedsOutput);
|
||||
Log.LogDebugMessage (" PrintMappingOutput: {0}", PrintMappingOutput);
|
||||
|
||||
// Windows seems to need special care, needs JAVA_TOOL_OPTIONS.
|
||||
// On the other hand, xbuild has a bug and fails to parse '=' in the value, so we skip JAVA_TOOL_OPTIONS on Mono runtime.
|
||||
EnvironmentVariables =
|
||||
string.IsNullOrEmpty (MSBuildRuntimeType) || MSBuildRuntimeType == "Mono" ?
|
||||
new string [] { "PROGUARD_HOME=" + ProguardHome } :
|
||||
new string [] { "JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8", "PROGUARD_HOME=" + ProguardHome };
|
||||
|
||||
return base.Execute ();
|
||||
}
|
||||
|
||||
|
@ -150,7 +166,7 @@ namespace Xamarin.Android.Tasks
|
|||
GetType ().Assembly.GetManifestResourceStream ("proguard_xamarin.cfg").CopyTo (xamcfg);
|
||||
|
||||
var configs = ProguardConfigurationFiles
|
||||
.Replace ("{sdk.dir}", Path.GetDirectoryName (Path.GetDirectoryName (ProguardHome)) + Path.DirectorySeparatorChar)
|
||||
.Replace ("{sdk.dir}", AndroidSdkDirectory + Path.DirectorySeparatorChar)
|
||||
.Replace ("{intermediate.common.xamarin}", ProguardCommonXamarinConfiguration)
|
||||
.Replace ("{intermediate.references}", ProguardGeneratedReferenceConfiguration)
|
||||
.Replace ("{intermediate.application}", ProguardGeneratedApplicationConfiguration)
|
||||
|
@ -187,35 +203,21 @@ namespace Xamarin.Android.Tasks
|
|||
cmd.AppendSwitchIfNotNull ("-printmapping ", PrintMappingOutput);
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/questions/5701126/compile-with-proguard-gives-exception-local-variable-type-mismatch#7587680
|
||||
cmd.AppendSwitch ("-optimizations !code/allocation/variable");
|
||||
|
||||
return cmd.ToString ();
|
||||
}
|
||||
|
||||
protected override string GenerateFullPathToTool ()
|
||||
{
|
||||
if (UseProguard)
|
||||
return Path.Combine (ToolPath, ToolExe);
|
||||
return Path.Combine (ProguardToolPath, "bin", ToolExe);
|
||||
return Path.Combine (JavaToolPath, ToolName);
|
||||
}
|
||||
|
||||
// Windows seems to need special care.
|
||||
protected override StringDictionary EnvironmentOverride {
|
||||
get {
|
||||
var sd = base.EnvironmentOverride ?? new StringDictionary ();
|
||||
if (OS.IsWindows) {
|
||||
if (!sd.ContainsKey ("PROGUARD_HOME"))
|
||||
sd.Add ("PROGUARD_HOME", ProguardHome);
|
||||
}
|
||||
var opts = sd.ContainsKey ("JAVA_TOOL_OPTIONS") ? sd ["JAVA_TOOL_OPTIONS"] : null;
|
||||
opts += " -Dfile.encoding=UTF8";
|
||||
sd ["JAVA_TOOL_OPTIONS"] = opts;
|
||||
return sd;
|
||||
}
|
||||
}
|
||||
|
||||
string ProguardHome {
|
||||
get {
|
||||
return Path.GetDirectoryName (Path.GetDirectoryName (UseProguard ? ToolPath : ProguardJarPath));
|
||||
}
|
||||
get { return UseProguard ? ProguardToolPath : Path.GetDirectoryName (Path.GetDirectoryName (ProguardJarPath)); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -742,14 +742,15 @@ because xbuild doesn't support framework reference assemblies.
|
|||
/>
|
||||
</CreateProperty>
|
||||
|
||||
<CreateProperty Value="$(AndroidSdkDirectory)\tools\proguard\lib\proguard.jar">
|
||||
<Output TaskParameter="Value" PropertyName="ProguardJarPath"
|
||||
Condition="'$(ProguardJarPath)' == ''"
|
||||
/>
|
||||
</CreateProperty>
|
||||
<CreateProperty Value="$(AndroidSdkDirectory)\tools\proguard\">
|
||||
<Output TaskParameter="Value" PropertyName="ProguardToolPath"
|
||||
Condition="'$(UseProguard)' == 'True' And '$(ProguardToolPath)' == ''"
|
||||
Condition="'$(ProguardToolPath)' == ''"
|
||||
/>
|
||||
</CreateProperty>
|
||||
|
||||
<CreateProperty Value="$(ProguardToolPath)lib\proguard.jar">
|
||||
<Output TaskParameter="Value" PropertyName="ProguardJarPath"
|
||||
Condition="'$(ProguardJarPath)' == ''"
|
||||
/>
|
||||
</CreateProperty>
|
||||
|
||||
|
@ -1883,6 +1884,7 @@ because xbuild doesn't support framework reference assemblies.
|
|||
StubSourceDirectory="$(IntermediateOutputPath)android\src"
|
||||
JavaSourceFiles="@(AndroidJavaSource)"
|
||||
JavaPlatformJackPath="$(_JavaPlatformJackPath)"
|
||||
AndroidSdkDirectory="$(_AndroidSdkDirectory)"
|
||||
InputJackFiles="@(_PreprocessedJavaLibrary)"
|
||||
OutputDexDirectory="$(IntermediateOutputPath)android\bin"
|
||||
ToolPath="$(JavaToolPath)"
|
||||
|
@ -2021,8 +2023,10 @@ because xbuild doesn't support framework reference assemblies.
|
|||
<Proguard
|
||||
Condition="'$(AndroidEnableProguard)' == 'True' and '$(_ProguardProjectConfiguration)' != ''"
|
||||
ProguardJarPath="$(ProguardJarPath)"
|
||||
AndroidSdkDirectory="$(_AndroidSdkDirectory)"
|
||||
JavaToolPath="$(JavaToolPath)"
|
||||
ToolPath="$(ProguardToolPath)"
|
||||
MSBuildRuntimeType="$(MSBuildRuntimeType)"
|
||||
ProguardToolPath="$(ProguardToolPath)"
|
||||
ToolExe="$(ProguardToolExe)"
|
||||
UseProguard="$(UseProguard)"
|
||||
JavaPlatformJarPath="$(JavaPlatformJarPath)"
|
||||
|
@ -2048,6 +2052,8 @@ because xbuild doesn't support framework reference assemblies.
|
|||
Condition="'$(AndroidEnableMultiDex)' == 'True' And '$(AndroidCustomMainDexListFile)' == ''"
|
||||
ToolPath="$(MainDexClassesToolPath)"
|
||||
ToolExe="$(MainDexClassesToolExe)"
|
||||
MSBuildRuntimeType="$(MSBuildRuntimeType)"
|
||||
ProguardHome="$(ProguardToolPath)"
|
||||
ClassesOutputDirectory="$(IntermediateOutputPath)android\bin\classes"
|
||||
JavaLibraries="@(_JavaLibrariesToCompile)"
|
||||
MultiDexMainDexListFile="$(_AndroidMainDexListFile)"
|
||||
|
|
Загрузка…
Ссылка в новой задаче