Skip to content

Commit ab45fd0

Browse files
Fix sort ordering for ndk-bundle, add macOS support
Context: https://build.azdo.io/xamarin/public/21545 An environment change on Azure DevOps seems to cause the test failure on Windows: Ndk_PathInSdk AndroidNdkPath not found inside sdk! Expected string length 71 but was 53. Strings differ at index 3. Expected: "C:\Users\VssAdministrator\AppData\Local\Temp\tmpAE78.tmp\sdk\..." But was: "C:\Program Files (x86)\Android\android-sdk\ndk-bundle" It appears that `xamarin-android-tools` is preferring an `ndk-bundle found on the system instead of the value passed in for `AndroidSdkPath`. To make matters worse, use of `Distinct()` returns an unordered sequence, and so the sort ordering is unknown: https://docs.microsoft.com/dotnet/api/system.linq.enumerable.distinct To fix this, let's not use `ToList()` or add `AndroidSdkPath` to the list at all. We can make an explicit check for it before the `foreach` loop. Inside the loop we should skip `AndroidSdkPath`. I also added the same code for the macOS/linux side in `AndroidSdkUnix`. I updated the `Ndk_PathInSdk` test so it will run on all platforms.
1 parent 3974fc3 commit ab45fd0

File tree

3 files changed

+37
-11
lines changed

3 files changed

+37
-11
lines changed

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,24 @@ protected override IEnumerable<string> GetAllAvailableAndroidNdks ()
125125
if (ValidateAndroidNdkLocation (ndkDir))
126126
yield return ndkDir;
127127
}
128+
129+
// Check for the "ndk-bundle" directory inside the SDK directories
130+
string ndk;
131+
132+
if (!string.IsNullOrEmpty (AndroidSdkPath) &&
133+
Directory.Exists (ndk = Path.Combine (AndroidSdkPath, "ndk-bundle"))) {
134+
if (ValidateAndroidNdkLocation (ndk))
135+
yield return ndk;
136+
}
137+
138+
foreach (var sdk in GetAllAvailableAndroidSdks ()) {
139+
if (sdk == AndroidSdkPath)
140+
continue;
141+
if (Directory.Exists (ndk = Path.Combine (sdk, "ndk-bundle"))) {
142+
if (ValidateAndroidNdkLocation (ndk))
143+
yield return ndk;
144+
}
145+
}
128146
}
129147

130148
protected override string GetShortFormPath (string path)

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

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -232,14 +232,20 @@ protected override IEnumerable<string> GetAllAvailableAndroidNdks ()
232232
// Check for the "ndk-bundle" directory inside the SDK directories
233233
string ndk;
234234

235-
var sdks = GetAllAvailableAndroidSdks().ToList();
236-
if (!string.IsNullOrEmpty(AndroidSdkPath))
237-
sdks.Add (AndroidSdkPath!);
238-
239-
foreach(var sdk in sdks.Distinct())
240-
if (Directory.Exists(ndk = Path.Combine(sdk, "ndk-bundle")))
241-
if (ValidateAndroidNdkLocation(ndk))
235+
if (!string.IsNullOrEmpty (AndroidSdkPath) &&
236+
Directory.Exists (ndk = Path.Combine (AndroidSdkPath, "ndk-bundle"))) {
237+
if (ValidateAndroidNdkLocation (ndk))
238+
yield return ndk;
239+
}
240+
241+
foreach (var sdk in GetAllAvailableAndroidSdks ()) {
242+
if (sdk == AndroidSdkPath)
243+
continue;
244+
if (Directory.Exists (ndk = Path.Combine (sdk, "ndk-bundle"))) {
245+
if (ValidateAndroidNdkLocation (ndk))
242246
yield return ndk;
247+
}
248+
}
243249

244250
// Check for the key the user gave us in the VS/addin options
245251
foreach (var root in roots)

tests/Xamarin.Android.Tools.AndroidSdk-Tests/AndroidSdkInfoTests.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,29 +67,31 @@ public void Constructor_Paths ()
6767
[Test]
6868
public void Ndk_PathInSdk()
6969
{
70-
if (!OS.IsWindows)
71-
Assert.Ignore("This only works in Windows");
72-
7370
CreateSdks(out string root, out string jdk, out string ndk, out string sdk);
7471

7572
var logs = new StringWriter();
7673
Action<TraceLevel, string> logger = (level, message) => {
7774
logs.WriteLine($"[{level}] {message}");
7875
};
7976

77+
var oldPath = Environment.GetEnvironmentVariable ("PATH", EnvironmentVariableTarget.Process);
8078
try
8179
{
80+
Environment.SetEnvironmentVariable ("PATH", "", EnvironmentVariableTarget.Process);
81+
82+
var extension = OS.IsWindows ? ".cmd" : "";
8283
var ndkPath = Path.Combine(sdk, "ndk-bundle");
8384
Directory.CreateDirectory(ndkPath);
8485
Directory.CreateDirectory(Path.Combine(ndkPath, "toolchains"));
85-
File.WriteAllText(Path.Combine(ndkPath, "ndk-stack.cmd"), "");
86+
File.WriteAllText(Path.Combine(ndkPath, $"ndk-stack{extension}"), "");
8687

8788
var info = new AndroidSdkInfo(logger, androidSdkPath: sdk, androidNdkPath: null, javaSdkPath: jdk);
8889

8990
Assert.AreEqual(ndkPath, info.AndroidNdkPath, "AndroidNdkPath not found inside sdk!");
9091
}
9192
finally
9293
{
94+
Environment.SetEnvironmentVariable ("PATH", oldPath, EnvironmentVariableTarget.Process);
9395
Directory.Delete(root, recursive: true);
9496
}
9597
}

0 commit comments

Comments
 (0)