Skip to content

Commit 0353506

Browse files
jonathanpeppersjonpryor
authored andcommitted
[Xamarin.Android.Build.Tasks] locate $(JdkJvmPath) only when needed (#2420)
Fixes: #2409 Context: https://github.com/xamarin/xamarin-android/wiki/Build-Performance-Results When doing the latest performance comparison, I noticed that the `<ResolveSdks/>` MSBuild task is a bit slower: * VS 15.9: 80 ms ResolveSdks 7 calls * VS 16.0 P2 (master) 127 ms ResolveSdks 7 calls For `$(AndroidGenerateJniMarshalMethods)` support, we needed to locate a new `$(JdkJvmPath)` location. Since `<ResolveSdks/>` finds `$(JdkJvmPath)` on the first build and design-time builds, it is worth making sure this task doesn't get any slower. The initial design-time build happens on "solution create", which is one of the more important metrics the VS team measures. Split out the logic finding `$(JdkJvmPath)` and put it in a new `<ResolveJdkJvmPath/>` MSBuild task. Also setup a `Condition`, so it only runs if: * Not a `$(DesignTimeBuild)` * `$(AndroidGenerateJniMarshalMethods)` is enabled * `$(JdkJvmPath)` is blank This should save ~50ms on Design-Time-Builds and first builds.
1 parent 143f397 commit 0353506

File tree

4 files changed

+78
-51
lines changed

4 files changed

+78
-51
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using Microsoft.Build.Framework;
2+
using Microsoft.Build.Utilities;
3+
using System;
4+
using System.IO;
5+
using System.Linq;
6+
using Xamarin.Android.Tools;
7+
8+
namespace Xamarin.Android.Tasks
9+
{
10+
/// <summary>
11+
/// This MSBuild task's job is to find $(JdkJvmPath) used by $(AndroidGenerateJniMarshalMethods)
12+
/// </summary>
13+
public class ResolveJdkJvmPath : Task
14+
{
15+
public string JavaSdkPath { get; set; }
16+
17+
[Output]
18+
public string JdkJvmPath { get; set; }
19+
20+
public override bool Execute ()
21+
{
22+
try {
23+
JdkJvmPath = GetJvmPath ();
24+
} catch (Exception e) {
25+
Log.LogCodedError ("XA5300", $"Unable to find {nameof (JdkJvmPath)}{Environment.NewLine}{e}");
26+
return false;
27+
}
28+
29+
if (string.IsNullOrEmpty (JdkJvmPath)) {
30+
Log.LogCodedError ("XA5300", $"{nameof (JdkJvmPath)} is blank");
31+
return false;
32+
}
33+
34+
if (!File.Exists (JdkJvmPath)) {
35+
Log.LogCodedError ("XA5300", $"JdkJvmPath not found at {JdkJvmPath}");
36+
return false;
37+
}
38+
39+
return !Log.HasLoggedErrors;
40+
}
41+
42+
string GetJvmPath ()
43+
{
44+
var key = new Tuple<string, string> (nameof (ResolveJdkJvmPath), JavaSdkPath);
45+
var cached = BuildEngine4.GetRegisteredTaskObject (key, RegisteredTaskObjectLifetime.AppDomain) as string;
46+
if (cached != null) {
47+
Log.LogDebugMessage ($"Using cached value for {nameof (JdkJvmPath)}: {cached}");
48+
49+
return cached;
50+
}
51+
52+
JdkInfo info = null;
53+
try {
54+
info = new JdkInfo (JavaSdkPath);
55+
} catch {
56+
info = JdkInfo.GetKnownSystemJdkInfos (this.CreateTaskLogger ()).FirstOrDefault ();
57+
}
58+
59+
if (info == null)
60+
return null;
61+
62+
var path = info.JdkJvmPath;
63+
if (string.IsNullOrEmpty (path))
64+
return null;
65+
66+
BuildEngine4.RegisterTaskObject (key, path, RegisteredTaskObjectLifetime.AppDomain, allowEarlyCollection: false);
67+
68+
return path;
69+
}
70+
}
71+
}

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

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ public class ResolveSdks : Task
5050
[Output]
5151
public string JavaSdkPath { get; set; }
5252

53-
[Output]
54-
public string JdkJvmPath { get; set; }
55-
5653
[Output]
5754
public string MonoAndroidToolsPath { get; set; }
5855

@@ -96,65 +93,18 @@ public override bool Execute ()
9693
return false;
9794
}
9895

99-
try {
100-
JdkJvmPath = GetJvmPath ();
101-
} catch (Exception e) {
102-
Log.LogCodedError ("XA5300", $"Unable to find {nameof (JdkJvmPath)}{Environment.NewLine}{e}");
103-
return false;
104-
}
105-
106-
if (string.IsNullOrEmpty (JdkJvmPath)) {
107-
Log.LogCodedError ("XA5300", $"{nameof (JdkJvmPath)} is blank");
108-
return false;
109-
}
110-
111-
if (!File.Exists (JdkJvmPath)) {
112-
Log.LogCodedError ("XA5300", $"JdkJvmPath not found at {JdkJvmPath}");
113-
return false;
114-
}
115-
11696
MonoAndroidHelper.TargetFrameworkDirectories = ReferenceAssemblyPaths;
11797

11898
Log.LogDebugMessage ($"{nameof (ResolveSdks)} Outputs:");
11999
Log.LogDebugMessage ($" {nameof (AndroidSdkPath)}: {AndroidSdkPath}");
120100
Log.LogDebugMessage ($" {nameof (AndroidNdkPath)}: {AndroidNdkPath}");
121101
Log.LogDebugMessage ($" {nameof (JavaSdkPath)}: {JavaSdkPath}");
122-
Log.LogDebugMessage ($" {nameof (JdkJvmPath)}: {JdkJvmPath}");
123102
Log.LogDebugMessage ($" {nameof (MonoAndroidBinPath)}: {MonoAndroidBinPath}");
124103
Log.LogDebugMessage ($" {nameof (MonoAndroidToolsPath)}: {MonoAndroidToolsPath}");
125104

126105
//note: this task does not error out if it doesn't find all things. that's the job of the targets
127106
return !Log.HasLoggedErrors;
128107
}
129-
130-
string GetJvmPath ()
131-
{
132-
var key = new Tuple<string, string> (nameof (ResolveSdks), JavaSdkPath);
133-
var cached = BuildEngine4.GetRegisteredTaskObject (key, RegisteredTaskObjectLifetime.AppDomain) as string;
134-
if (cached != null) {
135-
Log.LogDebugMessage ($"Using cached value for {nameof (JdkJvmPath)}: {cached}");
136-
137-
return cached;
138-
}
139-
140-
Xamarin.Android.Tools.JdkInfo info = null;
141-
try {
142-
info = new Xamarin.Android.Tools.JdkInfo (JavaSdkPath);
143-
} catch {
144-
info = Xamarin.Android.Tools.JdkInfo.GetKnownSystemJdkInfos (this.CreateTaskLogger ()).FirstOrDefault ();
145-
}
146-
147-
if (info == null)
148-
return null;
149-
150-
var path = info.JdkJvmPath;
151-
if (string.IsNullOrEmpty (path))
152-
return null;
153-
154-
BuildEngine4.RegisterTaskObject (key, path, RegisteredTaskObjectLifetime.AppDomain, allowEarlyCollection: false);
155-
156-
return path;
157-
}
158108
}
159109
}
160110

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
<Compile Include="Tasks\AndroidUpdateResDir.cs" />
143143
<Compile Include="Tasks\AndroidSignPackage.cs" />
144144
<Compile Include="Tasks\RemoveDirFixed.cs" />
145+
<Compile Include="Tasks\ResolveJdkJvmPath.cs" />
145146
<Compile Include="Tasks\ResolveSdksTask.cs" />
146147
<Compile Include="Tasks\CompileToDalvik.cs" />
147148
<Compile Include="Tasks\AndroidToolTask.cs" />

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
2727
<UsingTask TaskName="Xamarin.Android.Tasks.ResolveSdks" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
2828
<UsingTask TaskName="Xamarin.Android.Tasks.ValidateJavaVersion" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
2929
<UsingTask TaskName="Xamarin.Android.Tasks.ResolveAndroidTooling" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
30+
<UsingTask TaskName="Xamarin.Android.Tasks.ResolveJdkJvmPath" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
3031
<UsingTask TaskName="Xamarin.Android.Tasks.Aapt" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
3132
<UsingTask TaskName="Xamarin.Android.Tasks.Aapt2Compile" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
3233
<UsingTask TaskName="Xamarin.Android.Tasks.Aapt2Link" AssemblyFile="Xamarin.Android.Build.Tasks.dll" />
@@ -710,10 +711,14 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
710711
<Output TaskParameter="AndroidNdkPath" PropertyName="_AndroidNdkDirectory" />
711712
<Output TaskParameter="AndroidSdkPath" PropertyName="_AndroidSdkDirectory" />
712713
<Output TaskParameter="JavaSdkPath" PropertyName="_JavaSdkDirectory" />
713-
<Output TaskParameter="JdkJvmPath" PropertyName="JdkJvmPath" Condition="'$(JdkJvmPath)' == ''" />
714714
<Output TaskParameter="MonoAndroidToolsPath" PropertyName="MonoAndroidToolsDirectory" />
715715
<Output TaskParameter="MonoAndroidBinPath" PropertyName="MonoAndroidBinDirectory" />
716716
</ResolveSdks>
717+
<ResolveJdkJvmPath
718+
JavaSdkPath="$(_JavaSdkDirectory)"
719+
Condition=" '$(DesignTimeBuild)' != 'True' And '$(AndroidGenerateJniMarshalMethods)' == 'True' And '$(JdkJvmPath)' == '' ">
720+
<Output TaskParameter="JdkJvmPath" PropertyName="JdkJvmPath" />
721+
</ResolveJdkJvmPath>
717722
<ValidateJavaVersion
718723
TargetFrameworkVersion="$(TargetFrameworkVersion)"
719724
AndroidSdkBuildToolsVersion="$(AndroidSdkBuildToolsVersion)"

0 commit comments

Comments
 (0)