5
// Michael Hutchinson <mhutch@xamarin.com>
7
// Copyright (c) 2011 Xamarin Inc. (http://xamarin.com)
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
// of this software and associated documentation files (the "Software"), to deal
11
// in the Software without restriction, including without limitation the rights
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
// copies of the Software, and to permit persons to whom the Software is
14
// furnished to do so, subject to the following conditions:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28
using System.Collections.Generic;
29
using MonoDevelop.Core;
31
using MonoMac.Foundation;
34
namespace MonoDevelop.MacDev
36
public static class AppleSdkSettings
38
const string SDK_KEY = "MonoDevelop.MacDev.AppleSdkRoot";
40
internal static string DefaultRoot {
42
// If the current developer root corresponds to a default SDK location for
43
// any of the supported configurations, return that as the default root. If
44
// they have configured an SDK in a non-default location, fall back to using
45
// the default location for the latest SDK.
46
if (DefaultRoots.Contains (DeveloperRoot))
48
return DefaultRoots [0];
52
// Put newer SDKs at the top as we scan from 0 -> List.Count
53
static readonly IList<string> DefaultRoots = new List<string> {
54
"/Applications/Xcode.app",
57
static DateTime lastWritten;
59
static string GetEnvLocation ()
61
return Environment.GetEnvironmentVariable ("MD_APPLE_SDK_ROOT");
64
static void GetNewPaths (FilePath root, out FilePath xcode, out FilePath vplist, out FilePath devroot)
67
vplist = root.Combine ("Contents", "version.plist");
68
devroot = root.Combine ("Contents", "Developer");
71
static void GetOldPaths (FilePath root, out FilePath xcode, out FilePath vplist, out FilePath devroot)
73
xcode = root.Combine ("Applications", "Xcode.app");
74
vplist = root.Combine ("Library", "version.plist");
78
static bool ValidatePaths (FilePath xcode, FilePath vplist, FilePath devroot)
80
return Directory.Exists (xcode)
81
&& Directory.Exists (devroot)
82
&& File.Exists (vplist)
83
&& File.Exists (xcode.Combine ("Contents", "Info.plist"));
86
internal static bool ValidateSdkLocation (FilePath location, out FilePath xcode, out FilePath vplist, out FilePath devroot)
88
GetNewPaths (location, out xcode, out vplist, out devroot);
89
if (ValidatePaths (xcode, vplist, devroot))
92
GetOldPaths (location, out xcode, out vplist, out devroot);
93
if (ValidatePaths (xcode, vplist, devroot))
99
internal static void SetConfiguredSdkLocation (FilePath location)
101
if (location.IsNullOrEmpty || location == DefaultRoots.First ())
103
if (location == PropertyService.Get<string> (SDK_KEY))
105
PropertyService.Set (SDK_KEY, location);
106
if (GetEnvLocation () != null) {
112
internal static FilePath GetConfiguredSdkLocation ()
114
return PropertyService.Get<string> (SDK_KEY, null);
117
static void SetInvalid ()
119
XcodePath = FilePath.Empty;
120
DeveloperRoot = FilePath.Empty;
121
DeveloperRootVersionPlist = FilePath.Empty;
125
lastWritten = DateTime.MinValue;
128
static AppleSdkSettings ()
130
MonoDevelop.MacInterop.Cocoa.InitMonoMac ();
138
DeveloperRoot = Environment.GetEnvironmentVariable ("MD_APPLE_SDK_ROOT");
139
if (DeveloperRoot.IsNullOrEmpty) {
140
DeveloperRoot = GetConfiguredSdkLocation ();
143
bool foundSdk = false;
144
FilePath xcode, vplist, devroot;
146
if (DeveloperRoot.IsNullOrEmpty) {
147
foreach (var v in DefaultRoots) {
148
if (ValidateSdkLocation (v, out xcode, out vplist, out devroot)) {
152
LoggingService.LogDebug ("Apple iOS SDK not found at '{0}'", v);
156
foundSdk = ValidateSdkLocation (DeveloperRoot, out xcode, out vplist, out devroot);
161
DeveloperRoot = devroot;
162
DeveloperRootVersionPlist = vplist;
169
var plist = XcodePath.Combine ("Contents", "Info.plist");
170
if (!File.Exists (plist))
172
lastWritten = File.GetLastWriteTime (plist);
174
// DTXCode was introduced after xcode 3.2.6 so it may not exist
175
using (var pool = new NSAutoreleasePool ()) {
176
var dict = NSDictionary.FromFile (plist);
178
if (dict.TryGetValue (new NSString ("DTXcode"), out value))
179
DTXcode = ((NSString) value).ToString ();
181
IsXcode4 = !string.IsNullOrEmpty (DTXcode) && int.Parse (DTXcode) >= 0400;
182
IsXcode42 = !string.IsNullOrEmpty (DTXcode) && int.Parse (DTXcode) >= 0420;
184
} catch (Exception ex) {
185
LoggingService.LogError ("Error loading Xcode information for prefix '" + DeveloperRoot + "'", ex);
190
public static FilePath DeveloperRoot { get; private set; }
192
public static FilePath DeveloperRootVersionPlist {
196
public static FilePath XcodePath {
200
public static void CheckChanged ()
202
var plist = XcodePath.Combine ("Contents", "Info.plist");
203
DateTime w = DateTime.MinValue;
204
if (File.Exists (plist))
205
w = File.GetLastWriteTime (plist);
206
if (w != lastWritten) {
212
public static bool IsValid { get; private set; }
213
public static string DTXcode { get; private set; }
214
public static bool IsXcode4 { get; private set; }
215
public static bool IsXcode42 { get; private set; }
217
public static event Action Changed;
220
class AppleSdkAboutInformation : ISystemInformationProvider
222
public string Description {
224
var sb = new System.Text.StringBuilder ();
225
sb.AppendLine ("Apple Developer Tools:");
226
if (!AppleSdkSettings.IsValid) {
227
sb.AppendLine ("\t(Not Found)");
228
return sb.ToString ();
231
using (var pool = new NSAutoreleasePool ()) {
232
var dict = NSDictionary.FromFile (AppleSdkSettings.XcodePath.Combine ("Contents", "Info.plist"));
233
sb.AppendFormat ("\t Xcode {0} ({1})",
234
dict[(NSString)"CFBundleShortVersionString"],
235
dict[(NSString)"CFBundleVersion"]);
238
dict = NSDictionary.FromFile (AppleSdkSettings.DeveloperRootVersionPlist);
239
sb.AppendFormat ("\t Build {0}",
240
dict[(NSString)"ProductBuildVersion"]);
242
return sb.ToString ();
b'\\ No newline at end of file'