This repository was archived by the owner on Aug 31, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 227
Expand file tree
/
Copy pathsetup_xcode_sdks.py
More file actions
215 lines (178 loc) · 7.04 KB
/
setup_xcode_sdks.py
File metadata and controls
215 lines (178 loc) · 7.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/bin/python
# Update these lists if you need different SDK versions!
iphoneos_versions = ["14.5", "14.4", "13.2", "12.1", "11.2"]
iphonesimulator_versions = ["14.5", "14.4", "13.2", "12.1", "11.2"]
macosx_versions = ["10.9"]
# This tool creates the symlinks required for Xcode builds of LiveCode.
#
# There are a few steps you need to take before you can run this tool:
#
# 1) Create a suitable directory ${dir} to hold your Xcode apps
#
# 2) Download and extract the various versions of Xcode that you need. You
# should install them to ${dir}/Xcode_${ver}.app. For example, Xcode 6.2
# should be installed as ${dir}/Xcode_6_2.app
#
# 3) Download and install any extra SDKs that you need, by loading each version
# of Xcode and using the Xcode -> Preferences -> Downloads window
#
# 3) Make ${dir}/Xcode.app a symlink to the newest version of Xcode available.
# For example, you could run:
#
# cd ${dir}
# ln -s Xcode_6_3.app Xcode.app
#
# 4) Update the lists of SDK versions (above)
#
# 5) Run this script:
#
# cd ${dir}
# sh /path/to/setup_xcode_sdks.sh
#
# 6) Open Xcode!
#
# open ${dir}/Xcode.app
import os
import os.path
import re
import subprocess
import sys
from distutils.version import LooseVersion
def min_sdk(versions):
if len(versions) == 0:
return None
return sorted(versions, key=LooseVersion)[0]
def sdk_path(xcode_app, platform, version):
tmpl = "{0}/Contents/Developer/Platforms/{1}.platform/Developer/SDKs/{1}{2}.sdk"
return os.path.abspath(tmpl.format(xcode_app, platform, version))
def plist_path(xcode_app, platform):
tmpl = "{}/Contents/Developer/Platforms/{}.platform/Info.plist"
return os.path.abspath(tmpl.format(xcode_app, platform))
def check_sdk_path(xcode_app, platform, version):
path = sdk_path(xcode_app, platform, version)
if os.path.exists(path) and os.path.isdir(path):
return path
else:
return None
def is_sdk_present(xcode_app, platform, version):
return check_sdk_path(xcode_app, platform, version) is not None
def xcode_paths(base_dir):
return_list = []
level_0 = os.listdir(base_dir)
for entry in level_0:
if(re.match(r"Xcode.*\.app", entry)):
return_list.append(entry)
if(not os.path.isdir(entry)):
continue
level_1 = os.listdir(entry)
for l1_entry in level_1:
if(re.match(r"Xcode.*\.app", l1_entry)):
return_list.append(entry + "/" + l1_entry)
return return_list
def target_xcode(base_dir, beta):
if beta:
return "{}/{}".format(base_dir, "Xcode-beta.app")
else:
return "{}/{}".format(base_dir, "Xcode.app")
class SDKInstaller(object):
def __init__(self, base_dir):
self._base_dir = base_dir
self._success = True
def _diagnostic(self, message):
print("# " + message)
def _status(self, state, message):
if state:
print("ok - " + message)
else:
print("not ok - " + message)
self._success = False
def install(self, platform, versions, beta):
target = target_xcode(self._base_dir, beta)
self._install_sdks(target, platform, versions)
self._set_sdk_minversion(target, platform, versions)
def is_successful(self):
return self._success
def _set_sdk_minversion(self, xcode_app, platform, versions):
self._diagnostic("Setting {} SDK minimum version".format(platform))
version = min_sdk(versions)
path = plist_path(xcode_app, platform)
cmd = ["/usr/bin/defaults", "write", path, "MinimumSDKVersion",
"'{}'".format(version)]
success = (subprocess.call(cmd) == 0)
self._status(success, "{} {}".format(platform, version))
def _find_sdk(self, platform, version):
for xcode_app in xcode_paths(self._base_dir):
path = check_sdk_path(xcode_app, platform, version)
if path is not None:
return os.path.realpath(path)
return None
def _install_sdk(self, xcode_app, platform, version):
desc = "{} {}".format(platform, version)
if is_sdk_present(xcode_app, platform, version):
self._status(True, desc)
return
target_sdk = self._find_sdk(platform, version)
if target_sdk is None:
self._status(False, desc)
return
install_path = sdk_path(xcode_app, platform, version)
try:
os.symlink(target_sdk, install_path)
self._status(True, desc)
except OSError as e:
self._diagnostic("{} failed: {}".format(install_path, e))
self._status(False, desc)
def _install_sdks(self, xcode_app, platform, versions):
self._diagnostic("Installing {} SDK symlinks".format(platform))
for version in versions:
self._install_sdk(xcode_app, platform, version)
class CachingSDKInstaller(SDKInstaller):
def __init__(self, base_dir, cache_dir):
super(CachingSDKInstaller, self).__init__(base_dir)
self._cache_dir = cache_dir
def _cached_sdk_path(self, platform, version):
tmpl = "{0}/{1}/{1}{2}.sdk"
return os.path.abspath(tmpl.format(self._cache_dir, platform, version))
def _check_cached_sdk_path(self, platform, version):
path = self._cached_sdk_path(platform, version)
if os.path.exists(path) and os.path.isdir(path):
return path
else:
return None
def _cache_sdk(self, platform, version):
# Check cache
cache = self._check_cached_sdk_path(platform, version)
if cache is not None:
return
# Search app bundles
original = super(CachingSDKInstaller, self)._find_sdk(platform, version)
if original is None:
return
# Copy the original into cache
# N.b. use `cp -a` in order to make sure all resource forks etc. are
# preserved
self._diagnostic("Caching {} {} SDK".format(platform, version))
cache = self._cached_sdk_path(platform, version)
platform_dir = os.path.dirname(cache)
if not os.path.isdir(platform_dir):
os.makedirs(platform_dir)
cmd = ["/bin/cp", "-a", original, cache]
subprocess.check_call(cmd)
def _find_sdk(self, platform, version):
# Any available SDKs should have already been cached
return self._check_cached_sdk_path(platform, version)
def _install_sdk(self, xcode_app, platform, version):
self._cache_sdk(platform, version)
super(CachingSDKInstaller, self)._install_sdk(xcode_app, platform, version)
if __name__ == "__main__":
if "--cache" in sys.argv:
installer = CachingSDKInstaller(".", "./XcodeSDKs")
else:
installer = SDKInstaller(".")
beta = "--beta" in sys.argv
installer.install("iPhoneOS", iphoneos_versions, beta)
installer.install("iPhoneSimulator", iphonesimulator_versions, beta)
installer.install("MacOSX", macosx_versions, beta)
if not installer.is_successful():
print("ERROR: Some SDKs couldn't be installed")
sys.exit(1)