Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Tasks/ResolveJdkJvmPath.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using Microsoft.Build.Framework;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let ask @jonpryor about that, as we already had the separate task once #2153 (review) and he suggested to do it in ResolveSdks instead.

Now the circumstances changed (the DTB performance is important), but I guess we can still keep it in ResolveSdks and add ResolveJvmPath bool parameter to specify, whether the task should also resolve the JvmPath? That parameter value would be: '$(AndroidGenerateJniMarshalMethods)' == 'True'

I am OK with both alternatives, just don't remember what was the reasoning for not having it in separate task.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My original concern was around consistency of the JVM path which was used:

This way we ensure that we're consistent. By using JdkInfo.GetKnownSystemJdkInfos(), it's possible that <ResolveSdks/> will provide one JDK path, but JdkJvmPath could come from a different path.

I believe that in the original incarnation of the <JdkInfo/> task added in PR #2153, <JdkInfo/> didn't accept an "input" Java SDK Path property, but simply re- computed the JVM path based on Xamarin.Android.Tools.JdkInfo, which might not find the same path <ResolveSdks/> would have come up with (in part because <ResolveSdks/> reads $(JavaSdkDirectory), which could be overridden to point to ~anywhere).

Keeping both the JavaSdkPath and JdkJvmPath logic within <ResolveSdks/> thus helped ensur a degree of consistency.

The approach here does afford consistency between the <ResolveJdkJvmPath/> and <ResolveSdks/> tasks, because of the ResolveJdkJvmPath.JavaSdkPath property, and the only way they could differ is if the path that <ResolveSdks/> computes is an "invalid" path as far as Xamarin.Android.Tools.JdkInfo is concerned, but that was already a possibility when it was within <ResolveSdks/>, because ResolveSdks.JavaSdkPath wasn't updated if new JdkInfo(JavaSdkPath) ever threw.

using Microsoft.Build.Utilities;
using System;
using System.IO;
using System.Linq;
using Xamarin.Android.Tools;

namespace Xamarin.Android.Tasks
{
/// <summary>
/// This MSBuild task's job is to find $(JdkJvmPath) used by $(AndroidGenerateJniMarshalMethods)
/// </summary>
public class ResolveJdkJvmPath : Task
{
public string JavaSdkPath { get; set; }

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

public override bool Execute ()
{
try {
JdkJvmPath = GetJvmPath ();
} catch (Exception e) {
Log.LogCodedError ("XA5300", $"Unable to find {nameof (JdkJvmPath)}{Environment.NewLine}{e}");
return false;
}

if (string.IsNullOrEmpty (JdkJvmPath)) {
Log.LogCodedError ("XA5300", $"{nameof (JdkJvmPath)} is blank");
return false;
}

if (!File.Exists (JdkJvmPath)) {
Log.LogCodedError ("XA5300", $"JdkJvmPath not found at {JdkJvmPath}");
return false;
}

return !Log.HasLoggedErrors;
}

string GetJvmPath ()
{
var key = new Tuple<string, string> (nameof (ResolveJdkJvmPath), JavaSdkPath);
var cached = BuildEngine4.GetRegisteredTaskObject (key, RegisteredTaskObjectLifetime.AppDomain) as string;
if (cached != null) {
Log.LogDebugMessage ($"Using cached value for {nameof (JdkJvmPath)}: {cached}");

return cached;
}

JdkInfo info = null;
try {
info = new JdkInfo (JavaSdkPath);
} catch {
info = JdkInfo.GetKnownSystemJdkInfos (this.CreateTaskLogger ()).FirstOrDefault ();
}

if (info == null)
return null;

var path = info.JdkJvmPath;
if (string.IsNullOrEmpty (path))
return null;

BuildEngine4.RegisterTaskObject (key, path, RegisteredTaskObjectLifetime.AppDomain, allowEarlyCollection: false);

return path;
}
}
}
50 changes: 0 additions & 50 deletions src/Xamarin.Android.Build.Tasks/Tasks/ResolveSdksTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ public class ResolveSdks : Task
[Output]
public string JavaSdkPath { get; set; }

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

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

Expand Down Expand Up @@ -96,65 +93,18 @@ public override bool Execute ()
return false;
}

try {
JdkJvmPath = GetJvmPath ();
} catch (Exception e) {
Log.LogCodedError ("XA5300", $"Unable to find {nameof (JdkJvmPath)}{Environment.NewLine}{e}");
return false;
}

if (string.IsNullOrEmpty (JdkJvmPath)) {
Log.LogCodedError ("XA5300", $"{nameof (JdkJvmPath)} is blank");
return false;
}

if (!File.Exists (JdkJvmPath)) {
Log.LogCodedError ("XA5300", $"JdkJvmPath not found at {JdkJvmPath}");
return false;
}

MonoAndroidHelper.TargetFrameworkDirectories = ReferenceAssemblyPaths;

Log.LogDebugMessage ($"{nameof (ResolveSdks)} Outputs:");
Log.LogDebugMessage ($" {nameof (AndroidSdkPath)}: {AndroidSdkPath}");
Log.LogDebugMessage ($" {nameof (AndroidNdkPath)}: {AndroidNdkPath}");
Log.LogDebugMessage ($" {nameof (JavaSdkPath)}: {JavaSdkPath}");
Log.LogDebugMessage ($" {nameof (JdkJvmPath)}: {JdkJvmPath}");
Log.LogDebugMessage ($" {nameof (MonoAndroidBinPath)}: {MonoAndroidBinPath}");
Log.LogDebugMessage ($" {nameof (MonoAndroidToolsPath)}: {MonoAndroidToolsPath}");

//note: this task does not error out if it doesn't find all things. that's the job of the targets
return !Log.HasLoggedErrors;
}

string GetJvmPath ()
{
var key = new Tuple<string, string> (nameof (ResolveSdks), JavaSdkPath);
var cached = BuildEngine4.GetRegisteredTaskObject (key, RegisteredTaskObjectLifetime.AppDomain) as string;
if (cached != null) {
Log.LogDebugMessage ($"Using cached value for {nameof (JdkJvmPath)}: {cached}");

return cached;
}

Xamarin.Android.Tools.JdkInfo info = null;
try {
info = new Xamarin.Android.Tools.JdkInfo (JavaSdkPath);
} catch {
info = Xamarin.Android.Tools.JdkInfo.GetKnownSystemJdkInfos (this.CreateTaskLogger ()).FirstOrDefault ();
}

if (info == null)
return null;

var path = info.JdkJvmPath;
if (string.IsNullOrEmpty (path))
return null;

BuildEngine4.RegisterTaskObject (key, path, RegisteredTaskObjectLifetime.AppDomain, allowEarlyCollection: false);

return path;
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
<Compile Include="Tasks\AndroidUpdateResDir.cs" />
<Compile Include="Tasks\AndroidSignPackage.cs" />
<Compile Include="Tasks\RemoveDirFixed.cs" />
<Compile Include="Tasks\ResolveJdkJvmPath.cs" />
<Compile Include="Tasks\ResolveSdksTask.cs" />
<Compile Include="Tasks\CompileToDalvik.cs" />
<Compile Include="Tasks\AndroidToolTask.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
<UsingTask TaskName="Xamarin.Android.Tasks.ResolveSdks" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
<UsingTask TaskName="Xamarin.Android.Tasks.ValidateJavaVersion" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
<UsingTask TaskName="Xamarin.Android.Tasks.ResolveAndroidTooling" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
<UsingTask TaskName="Xamarin.Android.Tasks.ResolveJdkJvmPath" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
<UsingTask TaskName="Xamarin.Android.Tasks.Aapt" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
<UsingTask TaskName="Xamarin.Android.Tasks.Aapt2Compile" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
<UsingTask TaskName="Xamarin.Android.Tasks.Aapt2Link" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
Expand Down Expand Up @@ -710,10 +711,14 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
<Output TaskParameter="AndroidNdkPath" PropertyName="_AndroidNdkDirectory" />
<Output TaskParameter="AndroidSdkPath" PropertyName="_AndroidSdkDirectory" />
<Output TaskParameter="JavaSdkPath" PropertyName="_JavaSdkDirectory" />
<Output TaskParameter="JdkJvmPath" PropertyName="JdkJvmPath" Condition="'$(JdkJvmPath)' == ''" />
<Output TaskParameter="MonoAndroidToolsPath" PropertyName="MonoAndroidToolsDirectory" />
<Output TaskParameter="MonoAndroidBinPath" PropertyName="MonoAndroidBinDirectory" />
</ResolveSdks>
<ResolveJdkJvmPath
JavaSdkPath="$(_JavaSdkDirectory)"
Condition=" '$(DesignTimeBuild)' != 'True' And '$(AndroidGenerateJniMarshalMethods)' == 'True' And '$(JdkJvmPath)' == '' ">
<Output TaskParameter="JdkJvmPath" PropertyName="JdkJvmPath" />
</ResolveJdkJvmPath>
<ValidateJavaVersion
Condition=" '$(DesignTimeBuild)' != 'True' "
TargetFrameworkVersion="$(TargetFrameworkVersion)"
Expand Down