Skip to content

Commit 40acc94

Browse files
dgovilpixar-oss
authored andcommitted
Support building for iOS and visionOS Simulators
Closes #3707 (Internal change: 2398792)
1 parent d6d6330 commit 40acc94

2 files changed

Lines changed: 110 additions & 35 deletions

File tree

build_scripts/apple_utils.py

Lines changed: 77 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,41 @@
1818
import platform
1919
import shlex
2020
import subprocess
21-
import glob
2221
from typing import Optional, List, Dict
2322

23+
2424
TARGET_NATIVE = "native"
2525
TARGET_X86 = "x86_64"
2626
TARGET_ARM64 = "arm64"
2727
TARGET_UNIVERSAL = "universal"
2828
TARGET_IOS = "iOS"
29+
TARGET_IOS_SIMULATOR = "iOSSimulator"
2930
TARGET_VISIONOS = "visionOS"
31+
TARGET_VISIONOS_SIMULATOR = "visionOSSimulator"
3032

31-
EMBEDDED_PLATFORMS = [TARGET_IOS, TARGET_VISIONOS]
33+
EMBEDDED_PLATFORMS = [TARGET_IOS, TARGET_IOS_SIMULATOR,
34+
TARGET_VISIONOS, TARGET_VISIONOS_SIMULATOR]
3235

3336
def GetBuildTargets():
34-
return [TARGET_NATIVE,
35-
TARGET_X86,
36-
TARGET_ARM64,
37-
TARGET_UNIVERSAL,
38-
TARGET_IOS,
39-
TARGET_VISIONOS]
37+
return [
38+
TARGET_NATIVE,
39+
TARGET_X86,
40+
TARGET_ARM64,
41+
TARGET_UNIVERSAL,
42+
TARGET_IOS,
43+
TARGET_IOS_SIMULATOR,
44+
TARGET_VISIONOS,
45+
TARGET_VISIONOS_SIMULATOR
46+
]
47+
48+
def normalizeBuildTarget(target: str) -> Optional[str]:
49+
"""Returns a case-normalized build target name, or
50+
None if the target is not recognized."""
51+
targetLower = target.casefold()
52+
for validTarget in GetBuildTargets():
53+
if targetLower == validTarget.casefold():
54+
return validTarget
55+
return None
4056

4157
def GetBuildTargetDefault():
4258
return TARGET_NATIVE
@@ -45,7 +61,8 @@ def MacOS():
4561
return platform.system() == "Darwin"
4662

4763
def TargetEmbeddedOS(context):
48-
return context.buildTarget in EMBEDDED_PLATFORMS
64+
targetLower = context.buildTarget.casefold()
65+
return targetLower in map(str.casefold, EMBEDDED_PLATFORMS)
4966

5067
def GetLocale():
5168
return sys.stdout.encoding or locale.getdefaultlocale()[1] or "UTF-8"
@@ -77,15 +94,16 @@ def GetTargetArch(context):
7794
return GetTargetArmArch()
7895

7996
if context.targetNative:
80-
macTargets = GetHostArch()
81-
else:
82-
if context.targetX86:
83-
macTargets = TARGET_X86
84-
if context.targetARM64:
85-
macTargets = GetTargetArmArch()
86-
if context.targetUniversal:
87-
macTargets = TARGET_X86 + ";" + GetTargetArmArch()
88-
return macTargets
97+
return GetHostArch()
98+
99+
if context.targetX86:
100+
return TARGET_X86
101+
if context.targetARM64:
102+
return GetTargetArmArch()
103+
if context.targetUniversal:
104+
return TARGET_X86 + ";" + GetTargetArmArch()
105+
106+
return None
89107

90108
def IsHostArm():
91109
return GetHostArch() != TARGET_X86
@@ -102,7 +120,7 @@ def GetTargetArchPair(context):
102120
primaryArch = TARGET_X86
103121
if context.targetARM64:
104122
primaryArch = GetTargetArmArch()
105-
if context.buildTarget in EMBEDDED_PLATFORMS:
123+
if TargetEmbeddedOS(context):
106124
primaryArch = GetTargetArmArch()
107125
if context.targetUniversal:
108126
primaryArch = GetHostArch()
@@ -123,33 +141,49 @@ def GetSDKName(context) -> str:
123141
sdk = "macosx"
124142
if context.buildTarget == TARGET_IOS:
125143
sdk = "iPhoneOS"
144+
elif context.buildTarget == TARGET_IOS_SIMULATOR:
145+
sdk = "iPhoneSimulator"
126146
elif context.buildTarget == TARGET_VISIONOS:
127147
sdk = "xrOS"
148+
elif context.buildTarget == TARGET_VISIONOS_SIMULATOR:
149+
sdk = "xrSimulator"
150+
128151
return sdk
129152

130153
def GetSDKRoot(context) -> Optional[str]:
131154
sdk = GetSDKName(context).lower()
155+
132156
for arg in (context.cmakeBuildArgs or '').split():
133157
if "CMAKE_OSX_SYSROOT" in arg:
134158
override = arg.split('=')[1].strip('"').strip()
135159
if override:
136160
sdk = override
161+
137162
sdkroot = GetCommandOutput(["xcrun", "--sdk", sdk, "--show-sdk-path"])
138163
if not sdkroot:
139164
raise RuntimeError(f"Could not find an sdk path. Make sure you have the {sdk} sdk installed.")
140165
return sdkroot
141166

142-
def SetTarget(context, targetName):
167+
def GetSDKVersion(context):
168+
sdk_basename = os.path.basename(GetSDKRoot(context))
169+
return re.search(r'\d+\.\d+', sdk_basename).group()
170+
171+
def SetTarget(context):
172+
targetName = normalizeBuildTarget(context.buildTarget)
173+
context.buildTarget = targetName
143174
context.targetNative = (targetName == TARGET_NATIVE)
144175
context.targetX86 = (targetName == TARGET_X86)
145176
context.targetARM64 = (targetName == GetTargetArmArch())
146177
context.targetUniversal = (targetName == TARGET_UNIVERSAL)
147-
context.targetIOS = (targetName == TARGET_IOS)
148-
context.targetVisionOS = (targetName == TARGET_VISIONOS)
178+
context.targetIOS = (targetName in (TARGET_IOS, TARGET_IOS_SIMULATOR))
179+
context.targetVisionOS = (
180+
targetName in (TARGET_VISIONOS, TARGET_VISIONOS_SIMULATOR))
181+
context.targetSimulator = (
182+
targetName in (TARGET_IOS_SIMULATOR, TARGET_VISIONOS_SIMULATOR))
149183
if context.targetUniversal and not SupportsMacOSUniversalBinaries():
150184
context.targetUniversal = False
151185
raise ValueError(
152-
"Universal binaries only supported in macOS 11.0 and later.")
186+
"Universal binaries only supported in macOS 11.0 and later.")
153187

154188
def GetTargetName(context):
155189
return (TARGET_NATIVE if context.targetNative else
@@ -158,6 +192,9 @@ def GetTargetName(context):
158192
TARGET_UNIVERSAL if context.targetUniversal else
159193
context.buildTarget)
160194

195+
def GetTargetPlatform(context):
196+
return GetTargetName(context).replace("Simulator", "")
197+
161198
devout = open(os.devnull, 'w')
162199

163200
def ExtractFilesRecursive(path, cond):
@@ -240,7 +277,7 @@ def GetDevelopmentTeamID(identifier=None):
240277
["security", "find-certificate", "-c", identifier_hash, "-p"])
241278
subject = GetCommandOutput(["openssl", "x509", "-subject"], input=certs)
242279
subject = subject.splitlines()[0]
243-
match = re.search("OU\s*=\s*(?P<team>([A-Za-z0-9_])+)", subject)
280+
match = re.search(r"OU\s*=\s*(?P<team>([A-Za-z0-9_])+)", subject)
244281
if not match:
245282
raise RuntimeError("Could not parse the output "
246283
"certificate to find the team ID")
@@ -402,7 +439,7 @@ def CreateUniversalBinaries(context, libNames, x86Dir, armDir):
402439
def ConfigureCMakeExtraArgs(context, args:List[str]) -> List[str]:
403440
system_name = None
404441
if TargetEmbeddedOS(context):
405-
system_name = context.buildTarget
442+
system_name = GetTargetPlatform(context)
406443

407444
if system_name:
408445
args.append(f"-DCMAKE_SYSTEM_NAME={system_name}")
@@ -431,13 +468,26 @@ def GetTBBPatches(context):
431468
("iOS", context.buildTarget),
432469
("IPHONEOS",sdk_name.upper())]
433470

434-
if context.buildTarget == TARGET_VISIONOS:
471+
if context.buildTarget in (TARGET_VISIONOS, TARGET_VISIONOS_SIMULATOR):
435472
target_config_patches.extend([("iPhone", "XR"),
436473
("?= 8.0", "?= 1.0")])
437474

438475
clang_config_patches.append(("iPhone", "XR"),)
439476

440477
if context.buildTarget == TARGET_VISIONOS:
441-
clang_config_patches.append(("-miphoneos-version-min=", "-target arm64-apple-xros"))
478+
clang_config_patches.append(
479+
("-miphoneos-version-min=",
480+
"-target arm64-apple-xros"))
481+
else:
482+
version = GetSDKVersion(context)
483+
484+
if context.buildTarget == TARGET_VISIONOS_SIMULATOR:
485+
clang_config_patches.append(
486+
("-miphoneos-version-min=",
487+
f"-target arm64-apple-xros{version}-simulator"))
488+
elif context.buildTarget == TARGET_IOS_SIMULATOR:
489+
clang_config_patches.append(
490+
("-miphoneos-version-min=",
491+
f"-target arm64-apple-ios{version}-simulator"))
442492

443493
return target_config_patches, clang_config_patches

build_scripts/build_usd.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ def GetBuildTargetDefault():
9898

9999
def GetBuildTargets():
100100
if MacOS():
101-
return apple_utils.GetBuildTargets() + [TARGET_WASM, TARGET_WASM64]
101+
appleTargets = [str.casefold(x) for x in apple_utils.GetBuildTargets()]
102+
appleTargets.extend([TARGET_WASM, TARGET_WASM64])
103+
return appleTargets
102104
elif Linux():
103105
return [TARGET_WASM, TARGET_WASM64]
104106
elif Windows():
@@ -1082,24 +1084,47 @@ def InstallTBB_MacOS(context, force, buildArgs):
10821084
("ifeq ($(arch),$(filter $(arch),armv7 armv7s arm64))",
10831085
"ifeq ($(arch),$(filter $(arch),armv7 armv7s {0}))"
10841086
.format(apple_utils.GetTargetArmArch()))])
1085-
target_config_patches, clang_config_patches = \
1086-
apple_utils.GetTBBPatches(context)
1087-
if target_config_patches:
1087+
1088+
if (MacOSTargetEmbedded(context) and
1089+
context.buildTarget != apple_utils.TARGET_IOS):
1090+
target_patches, clang_patches = apple_utils.GetTBBPatches(context)
1091+
# Create config from iOS config
1092+
shutil.copy(
1093+
src="build/ios.macos.inc",
1094+
dst=f"build/{context.buildTarget.lower()}.macos.inc")
1095+
1096+
PatchFile(
1097+
f"build/{context.buildTarget.lower()}.macos.inc",
1098+
target_patches)
1099+
1100+
# iOS clang just reuses the macOS one,
1101+
# so it's easier to copy it directly.
1102+
shutil.copy(src="build/macos.clang.inc",
1103+
dst=f"build/{context.buildTarget.lower()}.clang.inc")
1104+
1105+
PatchFile(
1106+
f"build/{context.buildTarget.lower()}.clang.inc",
1107+
clang_patches)
1108+
1109+
primaryArch, secondaryArch = apple_utils.GetTargetArchPair(context)
1110+
target_patches, clang_patches = apple_utils.GetTBBPatches(context)
1111+
1112+
if target_patches:
10881113
# Create config from iOS config
10891114
shutil.copy(src="build/ios.macos.inc",
10901115
dst=f"build/{context.buildTarget.lower()}.macos.inc")
10911116

10921117
PatchFile(f"build/{context.buildTarget.lower()}.macos.inc",
1093-
target_config_patches)
1118+
target_patches)
10941119

1095-
if clang_config_patches:
1120+
if clang_patches:
10961121
# iOS clang just reuses the macOS one,
10971122
# so it's easier to copy it directly.
10981123
shutil.copy(src="build/macos.clang.inc",
10991124
dst=f"build/{context.buildTarget.lower()}.clang.inc")
11001125

11011126
PatchFile(f"build/{context.buildTarget.lower()}.clang.inc",
1102-
clang_config_patches)
1127+
clang_patches)
11031128

11041129
(primaryArch, secondaryArch) = apple_utils.GetTargetArchPair(context)
11051130

@@ -2404,7 +2429,7 @@ def __init__(self, args):
24042429
args.build_target == TARGET_WASM64)
24052430
self.buildTarget = args.build_target
24062431
if MacOS():
2407-
apple_utils.SetTarget(self, self.buildTarget)
2432+
apple_utils.SetTarget(self)
24082433

24092434
self.macOSCodesign = False
24102435
if args.macos_codesign:

0 commit comments

Comments
 (0)