Skip to content

Commit fbbf15a

Browse files
committed
[Xamarin.Android.Tools.AndroidSdk] Add JdkInfo
Context: #29 (comment) Refactor out the [underlying functionality][0] of the [`<JdkInfo/>` task][1] so that it is more easily usable. [0]: dotnet/java-interop@4bd9297 [1]: https://github.com/xamarin/java.interop/blob/master/src/Java.Interop.BootstrapTasks/Java.Interop.BootstrapTasks/JdkInfo.cs
1 parent 1b511f9 commit fbbf15a

File tree

9 files changed

+720
-91
lines changed

9 files changed

+720
-91
lines changed

src/Xamarin.Android.Tools.AndroidSdk/JdkInfo.cs

Lines changed: 418 additions & 0 deletions
Large diffs are not rendered by default.

src/Xamarin.Android.Tools.AndroidSdk/OS.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public class OS
1212

1313
internal readonly static string ProgramFilesX86;
1414

15+
internal readonly static string NativeLibraryFormat;
16+
1517
static OS ()
1618
{
1719
IsWindows = Path.DirectorySeparatorChar == '\\';
@@ -20,6 +22,13 @@ static OS ()
2022
if (IsWindows) {
2123
ProgramFilesX86 = GetProgramFilesX86 ();
2224
}
25+
26+
if (IsWindows)
27+
NativeLibraryFormat = "{0}.dll";
28+
if (IsMac)
29+
NativeLibraryFormat = "lib{0}.dylib";
30+
if (!IsWindows && !IsMac)
31+
NativeLibraryFormat = "lib{0}.so";
2332
}
2433

2534
//From Managed.Windows.Forms/XplatUI

src/Xamarin.Android.Tools.AndroidSdk/ProcessUtils.cs

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Diagnostics;
3-
using System.Threading.Tasks;
44
using System.IO;
55
using System.Threading;
6+
using System.Threading.Tasks;
67

78
namespace Xamarin.Android.Tools
89
{
910
public static class ProcessUtils
1011
{
12+
static string[] ExecutableFileExtensions;
13+
14+
static ProcessUtils ()
15+
{
16+
var pathExt = Environment.GetEnvironmentVariable ("PATHEXT");
17+
var pathExts = pathExt?.Split (new char [] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries) ?? new string [0];
18+
19+
ExecutableFileExtensions = pathExts;
20+
}
21+
1122
public static async Task<int> StartProcess (ProcessStartInfo psi, TextWriter stdout, TextWriter stderr, CancellationToken cancellationToken, Action<Process> onStarted = null)
1223
{
1324
cancellationToken.ThrowIfCancellationRequested ();
@@ -119,6 +130,62 @@ public static Task<TResult> ExecuteToolAsync<TResult> (string exe, Func<string,
119130

120131
return tcs.Task;
121132
}
133+
134+
internal static void Exec (ProcessStartInfo processStartInfo, DataReceivedEventHandler output)
135+
{
136+
processStartInfo.UseShellExecute = false;
137+
processStartInfo.RedirectStandardInput = false;
138+
processStartInfo.RedirectStandardOutput = true;
139+
processStartInfo.RedirectStandardError = true;
140+
processStartInfo.CreateNoWindow = true;
141+
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
142+
143+
var p = new Process () {
144+
StartInfo = processStartInfo,
145+
};
146+
p.OutputDataReceived += output;
147+
p.ErrorDataReceived += output;
148+
149+
using (p) {
150+
p.Start ();
151+
p.BeginOutputReadLine ();
152+
p.BeginErrorReadLine ();
153+
p.WaitForExit ();
154+
}
155+
}
156+
157+
internal static IEnumerable<string> FindExecutablesInPath (string executable)
158+
{
159+
var path = Environment.GetEnvironmentVariable ("PATH");
160+
var pathDirs = path.Split (new char[] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries);
161+
162+
foreach (var dir in pathDirs) {
163+
foreach (var exe in FindExecutablesInDirectory (dir, executable)) {
164+
yield return exe;
165+
}
166+
}
167+
}
168+
169+
internal static IEnumerable<string> FindExecutablesInDirectory (string dir, string executable)
170+
{
171+
foreach (var exe in ExecutableFiles (executable)) {
172+
var exePath = Path.Combine (dir, exe);
173+
if (File.Exists (exePath))
174+
yield return exePath;
175+
}
176+
}
177+
178+
internal static IEnumerable<string> ExecutableFiles (string executable)
179+
{
180+
if (ExecutableFileExtensions == null || ExecutableFileExtensions.Length == 0) {
181+
yield return executable;
182+
yield break;
183+
}
184+
185+
foreach (var ext in ExecutableFileExtensions)
186+
yield return Path.ChangeExtension (executable, ext);
187+
yield return executable;
188+
}
122189
}
123190
}
124191

src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkBase.cs

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -122,70 +122,39 @@ public string NdkHostPlatform {
122122
/// </summary>
123123
public bool ValidateAndroidSdkLocation (string loc)
124124
{
125-
return !string.IsNullOrEmpty (loc) && FindExecutableInDirectory (Adb, Path.Combine (loc, "platform-tools")).Any ();
125+
return !string.IsNullOrEmpty (loc) && ProcessUtils.FindExecutablesInDirectory (Path.Combine (loc, "platform-tools"), Adb).Any ();
126126
}
127127

128128
/// <summary>
129129
/// Checks that a value is the location of a Java SDK.
130130
/// </summary>
131131
public virtual bool ValidateJavaSdkLocation (string loc)
132132
{
133-
return !string.IsNullOrEmpty (loc) && FindExecutableInDirectory (JarSigner, Path.Combine (loc, "bin")).Any ();
133+
return !string.IsNullOrEmpty (loc) && ProcessUtils.FindExecutablesInDirectory (Path.Combine (loc, "bin"), JarSigner).Any ();
134134
}
135135

136136
/// <summary>
137137
/// Checks that a value is the location of an Android SDK.
138138
/// </summary>
139139
public bool ValidateAndroidNdkLocation (string loc)
140140
{
141-
return !string.IsNullOrEmpty (loc) && FindExecutableInDirectory (NdkStack, loc).Any ();
141+
return !string.IsNullOrEmpty (loc) && ProcessUtils.FindExecutablesInDirectory (loc, NdkStack).Any ();
142142
}
143143

144-
protected IEnumerable<string> FindExecutableInPath (string executable)
145-
{
146-
var path = Environment.GetEnvironmentVariable ("PATH");
147-
var pathDirs = path.Split (new char[] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries);
148-
149-
foreach (var dir in pathDirs) {
150-
foreach (var directory in FindExecutableInDirectory (executable, dir)) {
151-
yield return directory;
152-
}
153-
}
154-
}
155-
156-
protected IEnumerable<string> FindExecutableInDirectory (string executable, string dir)
157-
{
158-
foreach (var exe in Executables (executable))
159-
if (File.Exists (Path.Combine (dir, exe)))
160-
yield return dir;
161-
}
162-
163-
IEnumerable<string> Executables (string executable)
164-
{
165-
yield return executable;
166-
var pathExt = Environment.GetEnvironmentVariable ("PATHEXT");
167-
var pathExts = pathExt?.Split (new char [] { Path.PathSeparator }, StringSplitOptions.RemoveEmptyEntries);
168-
169-
if (pathExts == null)
170-
yield break;
171-
172-
foreach (var ext in pathExts)
173-
yield return Path.ChangeExtension (executable, ext);
174-
}
175-
176-
protected string NullIfEmpty (string s)
144+
protected static string NullIfEmpty (string s)
177145
{
178146
if (s == null || s.Length != 0)
179147
return s;
180148

181149
return null;
182150
}
183151

184-
string GetExecutablePath (string dir, string exe)
152+
static string GetExecutablePath (string dir, string exe)
185153
{
186154
if (string.IsNullOrEmpty (dir))
187155
return exe;
188-
foreach (var e in Executables (exe))
156+
157+
foreach (var e in ProcessUtils.ExecutableFiles (exe))
189158
if (File.Exists (Path.Combine (dir, e)))
190159
return e;
191160
return exe;

src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkUnix.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public override string NdkHostPlatform64Bit {
4242

4343
public override string PreferedAndroidSdkPath {
4444
get {
45-
var config_file = GetUnixConfigFile ();
45+
var config_file = GetUnixConfigFile (Logger);
4646
var androidEl = config_file.Root.Element ("android-sdk");
4747

4848
if (androidEl != null) {
@@ -57,7 +57,7 @@ public override string PreferedAndroidSdkPath {
5757

5858
public override string PreferedAndroidNdkPath {
5959
get {
60-
var config_file = GetUnixConfigFile ();
60+
var config_file = GetUnixConfigFile (Logger);
6161
var androidEl = config_file.Root.Element ("android-ndk");
6262

6363
if (androidEl != null) {
@@ -72,7 +72,7 @@ public override string PreferedAndroidNdkPath {
7272

7373
public override string PreferedJavaSdkPath {
7474
get {
75-
var config_file = GetUnixConfigFile ();
75+
var config_file = GetUnixConfigFile (Logger);
7676
var javaEl = config_file.Root.Element ("java-sdk");
7777

7878
if (javaEl != null) {
@@ -92,7 +92,7 @@ protected override IEnumerable<string> GetAllAvailableAndroidSdks ()
9292
yield return preferedSdkPath;
9393

9494
// Look in PATH
95-
foreach (var path in FindExecutableInPath (Adb)) {
95+
foreach (var path in ProcessUtils.FindExecutablesInPath (Adb)) {
9696
// Strip off "platform-tools"
9797
var dir = Path.GetDirectoryName (path);
9898

@@ -113,7 +113,7 @@ protected override string GetJavaSdkPath ()
113113
return preferedJavaSdkPath;
114114

115115
// Look in PATH
116-
foreach (var path in FindExecutableInPath (JarSigner)) {
116+
foreach (var path in ProcessUtils.FindExecutablesInPath (JarSigner)) {
117117
// Strip off "bin"
118118
var dir = Path.GetDirectoryName (path);
119119

@@ -160,7 +160,7 @@ protected override IEnumerable<string> GetAllAvailableAndroidNdks ()
160160
yield return preferedNdkPath;
161161

162162
// Look in PATH
163-
foreach (var path in FindExecutableInPath (NdkStack)) {
163+
foreach (var path in ProcessUtils.FindExecutablesInPath (NdkStack)) {
164164
if (ValidateAndroidNdkLocation (path))
165165
yield return path;
166166
}
@@ -176,7 +176,7 @@ public override void SetPreferredAndroidSdkPath (string path)
176176
{
177177
path = NullIfEmpty (path);
178178

179-
var doc = GetUnixConfigFile ();
179+
var doc = GetUnixConfigFile (Logger);
180180
var androidEl = doc.Root.Element ("android-sdk");
181181

182182
if (androidEl == null) {
@@ -192,7 +192,7 @@ public override void SetPreferredJavaSdkPath (string path)
192192
{
193193
path = NullIfEmpty (path);
194194

195-
var doc = GetUnixConfigFile ();
195+
var doc = GetUnixConfigFile (Logger);
196196
var javaEl = doc.Root.Element ("java-sdk");
197197

198198
if (javaEl == null) {
@@ -208,7 +208,7 @@ public override void SetPreferredAndroidNdkPath (string path)
208208
{
209209
path = NullIfEmpty (path);
210210

211-
var doc = GetUnixConfigFile ();
211+
var doc = GetUnixConfigFile (Logger);
212212
var androidEl = doc.Root.Element ("android-ndk");
213213

214214
if (androidEl == null) {
@@ -275,16 +275,16 @@ private static string UnixConfigPath {
275275
}
276276
}
277277

278-
private XDocument GetUnixConfigFile ()
278+
internal static XDocument GetUnixConfigFile (Action<TraceLevel, string> logger)
279279
{
280280
var file = UnixConfigPath;
281281
XDocument doc = null;
282282
if (File.Exists (file)) {
283283
try {
284284
doc = XDocument.Load (file);
285285
} catch (Exception ex) {
286-
Logger (TraceLevel.Error, "Could not load monodroid configuration file");
287-
Logger (TraceLevel.Verbose, ex.ToString ());
286+
logger (TraceLevel.Error, "Could not load monodroid configuration file");
287+
logger (TraceLevel.Verbose, ex.ToString ());
288288

289289
// move out of the way and create a new one
290290
doc = new XDocument (new XElement ("monodroid"));

0 commit comments

Comments
 (0)