Hello everyone, I have found very strange logic in Xamarin.MacDev to resolve the Xcode version to use. In my understanding, this logic doesn't work as expected and should be fixed.
I am talking about the following piece of code:
DeveloperRoot = Environment.GetEnvironmentVariable ("MD_APPLE_SDK_ROOT");
if (string.IsNullOrEmpty (DeveloperRoot)) {
DeveloperRoot = GetConfiguredSdkLocation (); // <--- this line always return non-null value
if (string.IsNullOrEmpty (DeveloperRoot) && File.Exists ("/usr/bin/xcode-select")) {
var startInfo = new ProcessStartInfo ("/usr/bin/xcode-select", "--print-path");
In my understanding, expected workflow is:
1) if MD_APPLE_SDK_ROOT is defined, use it
2) if ${HOME}/Library/Preferences/Xamarin/Settings.plist exists, read path from it
3) Otherwise, determine Xcode using /usr/bin/xcode-select --print-path
Currently, the third point never used because GetConfiguredSdkLocation always returns non-null value.
If plist is not found, it just returns default path /Applications/Xcode.app
public static string GetConfiguredSdkLocation ()
{
PDictionary plist;
PString value;
bool binary;
try {
if (File.Exists (SettingsPath))
plist = PDictionary.FromFile (SettingsPath, out binary);
else
plist = new PDictionary ();
} catch (FileNotFoundException) {
plist = new PDictionary ();
}
if (!plist.TryGetValue ("AppleSdkRoot", out value))
return DefaultRoots[0];
return value.Value;
}
How it affects us?
@maxim-lobanov you're linking to IDE (VS for Mac) and not SDK (Xamarin.iOS) code.
Also
DeveloperRoot = GetConfiguredSdkLocation (); // <--- this line always return non-null value
if (string.IsNullOrEmpty (DeveloperRoot) && File.Exists ("/usr/bin/xcode-select")) {
Your comment is right - but it does not matter if GetConfiguredSdkLocation always return non-null. An empty Plist should return an empty string (not /Applications/Xcode.app) and that's enough for the condition IsNullOrEmpty to query xcode-select (which might return /Applications/Xcode.app depending on your system).
I actually have some work locally to fix exactly this problem.
Your comment is right - but it does not matter if
GetConfiguredSdkLocationalways return non-null.
GetConfiguredSdkLocation always returns a non-null and non-empty string.
As a workaround, you can make sure xcode-select -p and the ~/Library/Preferences/Xamarin/Settings.plist point to the same Xcode like this:
/usr/libexec/PlistBuddy -c "add :AppleSdkRoot string $(dirname $(dirname $(xcode-select -p)))" ~/Library/Preferences/Xamarin/Settings.plist
Sorry, my first message was unclear. I meant that GetConfiguredSdkLocation always returns non-empty string so xcode-select is never called.
I am happy to see that @rolfbjarne has already addressed exactly same problem in https://github.com/xamarin/Xamarin.MacDev/pull/84. Changes look great and will resolve this issue. Thank you for doing it.
Am I right that these changes will be included to next Xamarin.iOS release?
Am I right that these changes will be included to next Xamarin.iOS release?
That is unclear, these changes not only affect Xamarin.iOS, but VSMac as well (due to shared code), so the risk is somewhat high.
We may backport this fix to a release branch, but we'll have to test it in our main dev branch first for a while.