Skip to content

Commit

Permalink
[build] java is no longer required in PATH
Browse files Browse the repository at this point in the history
Windows machines do not include Java in their path by default, so it is
a better experience to not require it for the build.

Changes to make this happen:
- A new `JavaPaths` MSBuild task that sets `JAVA_HOME`, and can return
the path to `javac` or `jar`
- The `JdkInfo` task has been changed to inherit from `JavaPaths`
- Usage of java command line tools througout the build are making use of
`JavaPaths` now
  • Loading branch information
jonathanpeppers committed Aug 31, 2017
1 parent bb808ad commit 215d396
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 65 deletions.
7 changes: 6 additions & 1 deletion build-tools/android-toolchain/android-toolchain.targets
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,12 @@
<_AndroidMxeOutput Include="@(_AndroidMxeToolchain->'$(AndroidMxeFullPath)\%(Identity)\lib\libz.a')" />
</ItemGroup>
<Target Name="_AcceptAndroidSdkLicenses">
<AcceptAndroidSdkLicenses AndroidSdkDirectory="$(AndroidSdkDirectory)" />
<JavaPaths
AndroidSdkPath="$(AndroidSdkPath)"
AndroidNdkPath="$(AndroidNdkPath)"
JavaSdkPath="$(JavaSdkDirectory)"
/>
<AcceptAndroidSdkLicenses AndroidSdkDirectory="$(AndroidSdkDirectory)" />
</Target>
<Target Name="_CreateMxeToolchains"
DependsOnTargets="_SetMxeToolchainMakefileTimeToLastCommitTimestamp"
Expand Down
4 changes: 2 additions & 2 deletions build-tools/dependencies/dependencies.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
<RequiredProgram Include="intltoolize" Condition=" '$(NeedMxe)' == 'true' And $(AndroidSupportedHostJitAbisForConditionalChecks.Contains (':mxe-Win64:'))">
<Homebrew>intltool</Homebrew>
</RequiredProgram>
<RequiredProgram Include="javac">
<RequiredProgram Include="$(_JavaC)">
<MinimumVersion>1.8</MinimumVersion>
<CurrentVersionCommand Condition=" '$(HostOS)' != 'Windows' ">$(MSBuildThisFileDirectory)..\scripts\javac-version</CurrentVersionCommand>
<CurrentVersionCommand Condition=" '$(HostOS)' == 'Windows' ">javac -version 2&gt;&amp;1</CurrentVersionCommand>
<CurrentVersionCommand Condition=" '$(HostOS)' == 'Windows' ">&quot;$(_JavaC)&quot; -version 2&gt;&amp;1</CurrentVersionCommand>
<UbuntuInstall>$(_AptGetInstall) openjdk-8-jdk</UbuntuInstall>
</RequiredProgram>
<RequiredProgram Include="make" Condition=" '$(HostOS)' != 'Windows' " />
Expand Down
14 changes: 11 additions & 3 deletions build-tools/scripts/JavaCallableWrappers.targets
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.JavaPaths" />
<Target Name="GenerateJavaCallableWrappers"
AfterTargets="$(JavaCallableWrapperAfterTargets)"
Inputs="$(JavaCallableWrapperAbsAssembly)"
Outputs="$(OutputPath)mono.android.jar">
<JavaPaths
AndroidSdkPath="$(AndroidSdkPath)"
AndroidNdkPath="$(AndroidNdkPath)"
JavaSdkPath="$(JavaSdkDirectory)">
<Output TaskParameter="JavaC" PropertyName="_JavaC" />
<Output TaskParameter="Jar" PropertyName="_Jar" />
</JavaPaths>
<MakeDir Directories="$(IntermediateOutputPath)jcw;$(IntermediateOutputPath)jcw\bin" />
<PropertyGroup>
<OutputPathAbs Condition="$([System.IO.Path]::IsPathRooted($(OutputPath)))">$(OutputPath)</OutputPathAbs>
Expand All @@ -30,15 +38,15 @@
<_MonoAndroidJar>$(OutputPath)mono.android.jar</_MonoAndroidJar>
</PropertyGroup>
<Exec
Command="javac $(_Target) $(_D) -bootclasspath $(_AndroidJar)$(PathSeparator)&quot;$(_MonoAndroidJar)&quot; @$(IntermediateOutputPath)jcw\classes.txt"
Command="&quot;$(_JavaC)&quot; $(_Target) $(_D) -bootclasspath $(_AndroidJar)$(PathSeparator)&quot;$(_MonoAndroidJar)&quot; @$(IntermediateOutputPath)jcw\classes.txt"
/>
<Exec
Condition="Exists('$(_MonoAndroidJar)')"
Command="jar uf &quot;$(_MonoAndroidJar)&quot; -C &quot;$(IntermediateOutputPath)jcw\bin&quot; ."
Command="&quot;$(_Jar)&quot; uf &quot;$(_MonoAndroidJar)&quot; -C &quot;$(IntermediateOutputPath)jcw\bin&quot; ."
/>
<Exec
Condition="!Exists('$(_MonoAndroidJar)')"
Command="jar cf &quot;$(_MonoAndroidJar)&quot; -C &quot;$(IntermediateOutputPath)jcw\bin&quot; ."
Command="&quot;$(_Jar)&quot; cf &quot;$(_MonoAndroidJar)&quot; -C &quot;$(IntermediateOutputPath)jcw\bin&quot; ."
/>
</Target>
<Target Name="_GenerateMonoAndroidDex16"
Expand Down
7 changes: 7 additions & 0 deletions build-tools/scripts/RequiredPrograms.targets
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.PrepareInstall" />
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.Which" />
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.GitCommitTime" />
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.JavaPaths" />
<Target Name="CheckForRequiredPrograms"
Condition=" '@(RequiredProgram)' != '' "
Inputs="@(RequiredProgram)"
Outputs="%(RequiredProgram.Identity)-BATCH">
<JavaPaths
AndroidSdkPath="$(AndroidSdkPath)"
AndroidNdkPath="$(AndroidNdkPath)"
JavaSdkPath="$(JavaSdkDirectory)">
<Output TaskParameter="JavaC" PropertyName="_JavaC" />
</JavaPaths>
<Which
HostOS="$(HostOS)"
HostOSName="$(HostOsName)"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System;
using System.IO;
using Xamarin.Android.Build.Utilities;

namespace Xamarin.Android.BuildTools.PrepTasks
{
public class JavaPaths : Task
{
public string AndroidNdkPath { get; set; }

public string AndroidSdkPath { get; set; }

public string JavaSdkPath { get; set; }

[Output]
public string JavaC { get; set; }

[Output]
public string Jar { get; set; }

public override bool Execute ()
{
LogMessages ();

AndroidLogger.Error += ErrorHandler;
AndroidLogger.Warning += WarningHandler;
AndroidLogger.Info += InfoHandler;
try {
AndroidSdk.Refresh (AndroidSdkPath, AndroidNdkPath, JavaSdkPath);

var javaSdkPath = AndroidSdk.JavaSdkPath;
if (string.IsNullOrEmpty (javaSdkPath)) {
Log.LogError ("JavaSdkPath is blank");
return false;
}

Log.LogMessage (MessageImportance.Low, $" {nameof (AndroidSdk.JavaSdkPath)}: {javaSdkPath}");

return SetOutput (javaSdkPath);
} finally {
AndroidLogger.Error -= ErrorHandler;
AndroidLogger.Warning -= WarningHandler;
AndroidLogger.Info -= InfoHandler;
}
}

protected virtual void LogMessages()
{
Log.LogMessage (MessageImportance.Low, $"Task {nameof (JavaPaths)}");
Log.LogMessage (MessageImportance.Low, $" {nameof (AndroidNdkPath)}: {AndroidNdkPath}");
Log.LogMessage (MessageImportance.Low, $" {nameof (AndroidSdkPath)}: {AndroidSdkPath}");
Log.LogMessage (MessageImportance.Low, $" {nameof (JavaSdkPath)}: {JavaSdkPath}");
}

protected virtual bool SetOutput(string javaSdkPath)
{
Environment.SetEnvironmentVariable ("JAVA_HOME", javaSdkPath);

var directories = new string [] { Path.Combine (javaSdkPath, "bin") };
string _;
JavaC = Which.GetProgramLocation ("javac", out _, directories);
Jar = Which.GetProgramLocation ("jar", out _, directories);

return !Log.HasLoggedErrors;
}

private void ErrorHandler (string task, string message)
{
Log.LogError ($"{task}: {message}");
}

private void WarningHandler (string task, string message)
{
Log.LogWarning ($"{task}: {message}");
}

private void InfoHandler (string task, string message)
{
Log.LogMessage (MessageImportance.Low, $"{task}: {message}");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,62 +1,44 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Xamarin.Android.Build.Utilities;

namespace Xamarin.Android.BuildTools.PrepTasks
{
public class JdkInfo : Task
public class JdkInfo : JavaPaths
{
[Required]
public ITaskItem Output { get; set; }

public string AndroidNdkPath { get; set; }

public string AndroidSdkPath { get; set; }

public string JavaSdkPath { get; set; }

public override bool Execute ()
protected override void LogMessages()
{
Log.LogMessage (MessageImportance.Low, $"Task {nameof (JdkInfo)}");
Log.LogMessage (MessageImportance.Low, $" {nameof (Output)}: {Output}");
Log.LogMessage (MessageImportance.Low, $" {nameof (AndroidNdkPath)}: {AndroidNdkPath}");
Log.LogMessage (MessageImportance.Low, $" {nameof (AndroidSdkPath)}: {AndroidSdkPath}");
Log.LogMessage (MessageImportance.Low, $" {nameof (JavaSdkPath)}: {JavaSdkPath}");
}

AndroidLogger.Error += ErrorHandler;
AndroidLogger.Warning += WarningHandler;
AndroidLogger.Info += InfoHandler;
try {
AndroidSdk.Refresh (AndroidSdkPath, AndroidNdkPath, JavaSdkPath);

var javaSdkPath = AndroidSdk.JavaSdkPath;
if (string.IsNullOrEmpty(javaSdkPath)) {
Log.LogError ("JavaSdkPath is blank");
return false;
}

Log.LogMessage (MessageImportance.Low, $" {nameof (AndroidSdk.JavaSdkPath)}: {javaSdkPath}");

var jvmPath = Path.Combine (javaSdkPath, "jre", "bin", "server", "jvm.dll");
if (!File.Exists (jvmPath)) {
Log.LogError ($"JdkJvmPath not found at {jvmPath}");
return false;
}
protected override bool SetOutput (string javaSdkPath)
{
var jvmPath = Path.Combine (javaSdkPath, "jre", "bin", "server", "jvm.dll");
if (!File.Exists (jvmPath)) {
Log.LogError ($"JdkJvmPath not found at {jvmPath}");
return false;
}

var javaIncludePath = Path.Combine (javaSdkPath, "include");
var includes = new List<string> { javaIncludePath };
includes.AddRange (Directory.GetDirectories (javaIncludePath)); //Include dirs such as "win32"
var javaIncludePath = Path.Combine (javaSdkPath, "include");
var includes = new List<string> { javaIncludePath };
includes.AddRange (Directory.GetDirectories (javaIncludePath)); //Include dirs such as "win32"

var includeXmlTags = new StringBuilder ();
foreach (var include in includes) {
includeXmlTags.AppendLine ($"<JdkIncludePath Include=\"{include}\" />");
}
var includeXmlTags = new StringBuilder ();
foreach (var include in includes) {
includeXmlTags.AppendLine ($"<JdkIncludePath Include=\"{include}\" />");
}

Directory.CreateDirectory (Path.GetDirectoryName (Output.ItemSpec));
File.WriteAllText (Output.ItemSpec, $@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
Directory.CreateDirectory (Path.GetDirectoryName (Output.ItemSpec));
File.WriteAllText (Output.ItemSpec, $@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
<Choose>
<When Condition="" '$(JdkJvmPath)' == '' "">
<PropertyGroup>
Expand All @@ -69,28 +51,7 @@ public override bool Execute ()
</Choose>
</Project>");

return !Log.HasLoggedErrors;
}
finally {
AndroidLogger.Error -= ErrorHandler;
AndroidLogger.Warning -= WarningHandler;
AndroidLogger.Info -= InfoHandler;
}
}

private void ErrorHandler (string task, string message)
{
Log.LogError ($"{task}: {message}");
}

private void WarningHandler (string task, string message)
{
Log.LogWarning ($"{task}: {message}");
}

private void InfoHandler (string task, string message)
{
Log.LogMessage (MessageImportance.Low, $"{task}: {message}");
return !Log.HasLoggedErrors;
}
}
}
1 change: 1 addition & 0 deletions build-tools/xa-prep-tasks/xa-prep-tasks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<Compile Include="Xamarin.Android.BuildTools.PrepTasks\GitCommitHash.cs" />
<Compile Include="Xamarin.Android.BuildTools.PrepTasks\GitCommitTime.cs" />
<Compile Include="Xamarin.Android.BuildTools.PrepTasks\HashFileContents.cs" />
<Compile Include="Xamarin.Android.BuildTools.PrepTasks\JavaPaths.cs" />
<Compile Include="Xamarin.Android.BuildTools.PrepTasks\JdkInfo.cs" />
<Compile Include="Xamarin.Android.BuildTools.PrepTasks\PathToolTask.cs" />
<Compile Include="Xamarin.Android.BuildTools.PrepTasks\SystemUnzip.cs" />
Expand Down
11 changes: 11 additions & 0 deletions src/proguard/proguard.targets
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask AssemblyFile="$(MSBuildThisFileDirectory)..\..\bin\Build$(Configuration)\xa-prep-tasks.dll" TaskName="Xamarin.Android.BuildTools.PrepTasks.JavaPaths" />
<Target Name="_BuildProGuard">
<JavaPaths
AndroidSdkPath="$(AndroidSdkPath)"
AndroidNdkPath="$(AndroidNdkPath)"
JavaSdkPath="$(JavaSdkDirectory)"
/>
<Exec
Command="$(AntDirectory)\bin\ant -verbose -f buildscripts\build.xml proguard"
WorkingDirectory="$(ProGuardSourceFullPath)"
Expand All @@ -24,6 +30,11 @@
</Target>
<Target Name="_CleanProGuard"
AfterTargets="Clean">
<JavaPaths
AndroidSdkPath="$(AndroidSdkPath)"
AndroidNdkPath="$(AndroidNdkPath)"
JavaSdkPath="$(JavaSdkDirectory)"
/>
<Delete Files="$(OutputPath)\license.html" />
<Delete Files="$(OutputPath)\lib\proguard.jar" />
<Delete Files="$(OutputPath)\bin\proguard.sh" />
Expand Down

0 comments on commit 215d396

Please sign in to comment.