Skip to content

Commit 3582b39

Browse files
[macOS] fix DirectoryNotFoundException on clean systems (#110)
@PureWeen was hitting a problem building a .NET 6 app on macOS: Task "ResolveSdks" ... at System.IO.Enumeration.FileSystemEnumerator`1.CreateDirectoryHandle(String path, Boolean ignoreNotFound) at System.IO.Enumeration.FileSystemEnumerator`1.Init() at System.IO.Enumeration.FileSystemEnumerator`1..ctor(String directory, Boolean isNormalized, EnumerationOptions options) at System.IO.Enumeration.FileSystemEnumerable`1..ctor(String directory, FindTransform transform, EnumerationOptions options, Boolean isNormalized) at System.IO.Enumeration.FileSystemEnumerableFactory.UserDirectories(String directory, String expression, EnumerationOptions options) at System.IO.Directory.InternalEnumeratePaths(String path, String searchPattern, SearchTarget searchTarget, EnumerationOptions options) at Xamarin.Android.Tools.AndroidSdkBase.FindBestNDK(String androidSdkPath) at Xamarin.Android.Tools.AndroidSdkBase.GetAllAvailableAndroidNdks()+MoveNext() at Xamarin.Android.Tools.AndroidSdkBase.GetValidNdkPath(String ctorParam) at Xamarin.Android.Tools.AndroidSdkBase.Initialize(String androidSdkPath, String androidNdkPath, String javaSdkPath) at Xamarin.Android.Tools.AndroidSdkInfo..ctor(Action`2 logger, String androidSdkPath, String androidNdkPath, String javaSdkPath) at Xamarin.Android.Tasks.MonoAndroidHelper.RefreshAndroidSdk(String sdkPath, String ndkPath, String javaPath, TaskLoggingHelper logHelper) at Xamarin.Android.Tasks.ResolveSdks.RunTask() at Microsoft.Android.Build.Tasks.AndroidTask.Execute() This was a relatively new Mac which didn't have an Android NDK installed. A way to workaround the problem was to create a directory that was being checked for: mkdir -p ~/Library/Android/sdk It appears this problem was introduced in b2d9fdf, as: 1. `~/Library/Android/sdk` is returned from [`GetAllAvailableAndroidNdks()`][0] 2. `GetAllAvailableAndroidNdks()` calls `GetAllAvailableAndroidSdks()` looking for any `ndk-bundle` folders it can find. 3. `FindBestNDK()` is passed a directory that doesn't exist, and the `Directory.EnumerateDirectories()` call [throw][1]. The fix here is to update `FindBestNDK()` to check `Directory.Exists()` before trying to traverse the directory `androidSdkPath`, as the values from `GetSdkFromEnvironmentVariables()` may not exist either. I was able to add a test for this scenario by adding an invalid directory to `$ANDROID_HOME`. [0]: https://github.com/xamarin/xamarin-android-tools/blob/b2d9fdf8782875ffb63da48cf8e0b385b04f7c25/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkUnix.cs#L113-L115 [1]: https://github.com/xamarin/xamarin-android-tools/blob/b2d9fdf8782875ffb63da48cf8e0b385b04f7c25/src/Xamarin.Android.Tools.AndroidSdk/Sdks/AndroidSdkBase.cs#L172
1 parent ca820e5 commit 3582b39

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ protected virtual IEnumerable<string> GetAllAvailableAndroidNdks ()
152152
// Look in PATH
153153
foreach (var ndkStack in ProcessUtils.FindExecutablesInPath (NdkStack)) {
154154
var ndkDir = Path.GetDirectoryName (ndkStack);
155-
if (ndkDir == null)
155+
if (string.IsNullOrEmpty (ndkDir))
156156
continue;
157157
yield return ndkDir;
158158
}
@@ -161,12 +161,19 @@ protected virtual IEnumerable<string> GetAllAvailableAndroidNdks ()
161161
foreach (var sdk in GetAllAvailableAndroidSdks ()) {
162162
if (sdk == AndroidSdkPath)
163163
continue;
164-
yield return FindBestNDK (sdk);
164+
var ndkDir = FindBestNDK (sdk);
165+
if (string.IsNullOrEmpty (ndkDir))
166+
continue;
167+
yield return ndkDir;
165168
}
166169
}
167170

168171
string FindBestNDK (string androidSdkPath)
169172
{
173+
if (!Directory.Exists (androidSdkPath)) {
174+
return String.Empty;
175+
}
176+
170177
var ndkInstances = new SortedDictionary<Version, string> (Comparer<Version>.Create ((Version l, Version r) => r.CompareTo (l)));
171178

172179
foreach (string ndkPath in Directory.EnumerateDirectories (androidSdkPath, "ndk*", SearchOption.TopDirectoryOnly)) {

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,28 @@ public void Ndk_PathInSdk()
146146
}
147147
}
148148

149+
[Test]
150+
public void Ndk_AndroidSdkDoesNotExist ()
151+
{
152+
CreateSdks (out string root, out string jdk, out string ndk, out string sdk);
153+
154+
Action<TraceLevel, string> logger = (level, message) => {
155+
Console.WriteLine ($"[{level}] {message}");
156+
if (level == TraceLevel.Error)
157+
Assert.Fail (message);
158+
};
159+
160+
var oldAndroidHome = Environment.GetEnvironmentVariable ("ANDROID_HOME");
161+
try {
162+
Environment.SetEnvironmentVariable ("ANDROID_HOME", "/i/dont/exist");
163+
// Check that this doesn't throw
164+
new AndroidSdkInfo (logger, androidSdkPath: sdk, androidNdkPath: null, javaSdkPath: jdk);
165+
} finally {
166+
Environment.SetEnvironmentVariable ("ANDROID_HOME", oldAndroidHome);
167+
Directory.Delete (root, recursive: true);
168+
}
169+
}
170+
149171
[Test]
150172
public void Constructor_SetValuesFromPath ()
151173
{

0 commit comments

Comments
 (0)