Skip to content
This repository was archived by the owner on Jul 13, 2026. It is now read-only.

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

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

‎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(varndkStackinProcessUtils.FindExecutablesInPath(NdkStack)){
154154
varndkDir=Path.GetDirectoryName(ndkStack);
155-
if(ndkDir==null)
155+
if(string.IsNullOrEmpty(ndkDir))
156156
continue;
157157
yieldreturnndkDir;
158158
}
@@ -161,12 +161,19 @@ protected virtual IEnumerable<string> GetAllAvailableAndroidNdks ()
161161
foreach(varsdkinGetAllAvailableAndroidSdks()){
162162
if(sdk==AndroidSdkPath)
163163
continue;
164-
yieldreturnFindBestNDK(sdk);
164+
varndkDir=FindBestNDK(sdk);
165+
if(string.IsNullOrEmpty(ndkDir))
166+
continue;
167+
yieldreturnndkDir;
165168
}
166169
}
167170

168171
stringFindBestNDK(stringandroidSdkPath)
169172
{
173+
if(!Directory.Exists(androidSdkPath)){
174+
returnString.Empty;
175+
}
176+
170177
varndkInstances=newSortedDictionary<Version,string>(Comparer<Version>.Create((Versionl,Versionr)=>r.CompareTo(l)));
171178

172179
foreach(stringndkPathinDirectory.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+
publicvoidNdk_AndroidSdkDoesNotExist()
151+
{
152+
CreateSdks(outstringroot,outstringjdk,outstringndk,outstringsdk);
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+
varoldAndroidHome=Environment.GetEnvironmentVariable("ANDROID_HOME");
161+
try{
162+
Environment.SetEnvironmentVariable("ANDROID_HOME","/i/dont/exist");
163+
// Check that this doesn't throw
164+
newAndroidSdkInfo(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
publicvoidConstructor_SetValuesFromPath()
151173
{

0 commit comments

Comments
 (0)