Skip to content

Commit b473209

Browse files
author
Thor Hjalmarsson
committed
iOS long term support
1 parent b53573e commit b473209

37 files changed

Lines changed: 132640 additions & 149 deletions

build_scripts/apple_utils.py

Lines changed: 101 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,20 @@
3535
import platform
3636
import shlex
3737
import subprocess
38+
import re
3839

3940
TARGET_NATIVE = "native"
4041
TARGET_X86 = "x86_64"
4142
TARGET_ARM64 = "arm64"
4243
TARGET_UNIVERSAL = "universal"
44+
TARGET_IOS = "ios"
4345

4446
def GetBuildTargets():
4547
return [TARGET_NATIVE,
4648
TARGET_X86,
4749
TARGET_ARM64,
48-
TARGET_UNIVERSAL]
50+
TARGET_UNIVERSAL,
51+
TARGET_IOS]
4952

5053
def GetBuildTargetDefault():
5154
return TARGET_NATIVE;
@@ -57,14 +60,52 @@ def GetLocale():
5760
return sys.stdout.encoding or locale.getdefaultlocale()[1] or "UTF-8"
5861

5962
def GetCommandOutput(command):
60-
"""Executes the specified command and returns output or None."""
63+
"""Executes the specified command and returns output or None.
64+
If command contains pipes (i.e '|'s), creates a subprocess for
65+
each pipe in command, returning the output from the last subcommand
66+
or None if any of the subcommands result in a CalledProcessError"""
67+
68+
result = None
69+
70+
args = shlex.split(command)
71+
commands = []
72+
cmd_args = []
73+
while args:
74+
arg = args.pop(0)
75+
if arg == '|':
76+
commands.append((cmd_args))
77+
cmd_args = []
78+
else:
79+
cmd_args.append(arg)
80+
commands.append((cmd_args))
81+
82+
pipes = []
83+
while len(commands) > 1:
84+
# We have some pipes
85+
command = commands.pop(0)
86+
stdin = pipes[-1].stdout if pipes else None
87+
try:
88+
pipe = subprocess.Popen(command, stdin=stdin, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
89+
pipes.append(pipe)
90+
except subprocess.CalledProcessError:
91+
return None
92+
93+
# The last command actually returns a result
94+
command = commands[0]
6195
try:
62-
return subprocess.check_output(
63-
shlex.split(command),
64-
stderr=subprocess.STDOUT).decode(GetLocale(), 'replace').strip()
96+
stdin = pipes[-1].stdout if pipes else None
97+
result = subprocess.check_output(
98+
command,
99+
stdin = stdin,
100+
stderr=subprocess.STDOUT).decode('utf-8').strip()
65101
except subprocess.CalledProcessError:
66102
pass
67-
return None
103+
104+
# clean-up
105+
for pipe in pipes:
106+
pipe.wait()
107+
108+
return result
68109

69110
def GetTargetArmArch():
70111
# Allows the arm architecture string to be overridden by
@@ -85,7 +126,7 @@ def GetTargetArch(context):
85126
else:
86127
if context.targetX86:
87128
macTargets = TARGET_X86
88-
if context.targetARM64:
129+
if context.targetARM64 or context.targetIos:
89130
macTargets = GetTargetArmArch()
90131
if context.targetUniversal:
91132
macTargets = TARGET_X86 + ";" + GetTargetArmArch()
@@ -106,6 +147,8 @@ def GetTargetArchPair(context):
106147
primaryArch = TARGET_X86
107148
if context.targetARM64:
108149
primaryArch = GetTargetArmArch()
150+
if context.targetIos:
151+
primaryArch = TARGET_IOS
109152
if context.targetUniversal:
110153
primaryArch = GetHostArch()
111154
if (primaryArch == TARGET_X86):
@@ -128,6 +171,17 @@ def SetTarget(context, targetName):
128171
context.targetX86 = (targetName == TARGET_X86)
129172
context.targetARM64 = (targetName == GetTargetArmArch())
130173
context.targetUniversal = (targetName == TARGET_UNIVERSAL)
174+
context.targetIos = (targetName == TARGET_IOS)
175+
if context.targetIos:
176+
sdkStr = GetCommandOutput('xcodebuild -showsdks')
177+
sdkStrSpl = sdkStr.split()
178+
for s in sdkStrSpl:
179+
if s.startswith('iphoneos'):
180+
s = s.replace('iphoneos', "")
181+
context.iosVersion = s
182+
break
183+
else:
184+
context.iosVersion = None
131185
if context.targetUniversal and not SupportsMacOSUniversalBinaries():
132186
self.targetUniversal = False
133187
raise ValueError(
@@ -138,6 +192,7 @@ def GetTargetName(context):
138192
TARGET_X86 if context.targetX86 else
139193
GetTargetArmArch() if context.targetARM64 else
140194
TARGET_UNIVERSAL if context.targetUniversal else
195+
TARGET_IOS if context.targetIos else
141196
"")
142197

143198
devout = open(os.devnull, 'w')
@@ -150,26 +205,54 @@ def ExtractFilesRecursive(path, cond):
150205
files.append(os.path.join(r, file))
151206
return files
152207

153-
def CodesignFiles(files):
154-
SDKVersion = subprocess.check_output(
155-
['xcodebuild', '-version']).strip()[6:10]
156-
codeSignIDs = subprocess.check_output(
157-
['security', 'find-identity', '-vp', 'codesigning'])
208+
def _GetCodeSignStringFromTerminal():
209+
codeSignIDs = subprocess.check_output(['security',
210+
'find-identity', '-vp', 'codesigning'])
211+
return codeSignIDs
158212

213+
def GetCodeSignID():
214+
codeSignIDs = _GetCodeSignStringFromTerminal()
159215
codeSignID = "-"
160216
if os.environ.get('CODE_SIGN_ID'):
161217
codeSignID = os.environ.get('CODE_SIGN_ID')
162-
elif float(SDKVersion) >= 11.0 and \
163-
codeSignIDs.find(b'Apple Development') != -1:
164-
codeSignID = "Apple Development"
165-
elif codeSignIDs.find(b'Mac Developer') != -1:
166-
codeSignID = "Mac Developer"
218+
else:
219+
try:
220+
codeSignID = codeSignIDs.decode("utf-8").split()[1]
221+
except:
222+
raise Exception("Unable to parse codesign ID")
223+
return codeSignID
224+
225+
def GetCodeSignIDHash():
226+
codeSignIDs = _GetCodeSignStringFromTerminal()
227+
try:
228+
return re.findall(r'\(.*?\)', codeSignIDs.decode("utf-8"))[0][1:-1]
229+
except:
230+
raise Exception("Unable to parse codesign ID hash")
231+
232+
def GetDevelopmentTeamID():
233+
if os.environ.get("DEVELOPMENT_TEAM"):
234+
return os.environ.get("DEVELOPMENT_TEAM")
235+
codesignID = GetCodeSignIDHash()
236+
x509subject = GetCommandOutput('security find-certificate -c {}'
237+
' -p | openssl x509 -subject | head -1'.format(codesignID)).strip()
238+
# Extract the Organizational Unit (OU field) from the cert
239+
try:
240+
team = [elm for elm in x509subject.split(
241+
'/') if elm.startswith('OU')][0].split('=')[1]
242+
if team is not None and team != "":
243+
return team
244+
except Exception as ex:
245+
raise Exception("No development team found with exception " + ex)
246+
247+
def CodesignFiles(files):
248+
codeSignID = GetCodeSignID()
167249

168250
for f in files:
169251
subprocess.call(['codesign', '-f', '-s', '{codesignid}'
170-
.format(codesignid=codeSignID), f],
252+
.format(codesignid=codeSignID), f],
171253
stdout=devout, stderr=devout)
172254

255+
173256
def Codesign(install_path, verbose_output=False):
174257
if not MacOS():
175258
return False

0 commit comments

Comments
 (0)