Skip to content

Commit 5a03c2c

Browse files
authored
Merge pull request #75 from cltnschlosser/cs_catalystSupport
Add support for catalyst
2 parents 983422b + 2881b43 commit 5a03c2c

13 files changed

+277
-41
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ public struct Driver {
7777
/// The target triple.
7878
public let targetTriple: Triple
7979

80+
/// The variant target triple.
81+
public let targetVariantTriple: Triple?
82+
8083
/// The toolchain to use for resolution.
8184
public let toolchain: Toolchain
8285

@@ -238,6 +241,7 @@ public struct Driver {
238241
Triple($0, normalizing: true)
239242
}
240243
(self.toolchain, self.targetTriple) = try Self.computeToolchain(explicitTarget, diagnosticsEngine: diagnosticEngine, env: env)
244+
self.targetVariantTriple = self.parsedOptions.getLastArgument(.targetVariant).map { Triple($0.asSingle, normalizing: true) }
241245

242246
// Find the Swift compiler executable.
243247
if let frontendPath = self.parsedOptions.getLastArgument(.driverUseFrontendPath) {

Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ extension DarwinToolchain {
114114

115115
private func addDeploymentTargetArgs(
116116
to commandLine: inout [Job.ArgTemplate],
117-
targetTriple: Triple
117+
targetTriple: Triple,
118+
targetVariantTriple: Triple?
118119
) {
119120
// FIXME: Properly handle deployment targets.
120121

@@ -125,6 +126,8 @@ extension DarwinToolchain {
125126
flag = "-iphoneos_version_min"
126127
case .iOS(.simulator):
127128
flag = "-ios_simulator_version_min"
129+
case .iOS(.catalyst):
130+
flag = "-maccatalyst_version_min"
128131
case .macOS:
129132
flag = "-macosx_version_min"
130133
case .tvOS(.device):
@@ -139,6 +142,20 @@ extension DarwinToolchain {
139142

140143
commandLine.appendFlag(flag)
141144
commandLine.appendFlag(targetTriple.version().description)
145+
146+
if let variant = targetVariantTriple {
147+
if targetTriple.isiOS {
148+
assert(targetTriple.isValidForZipperingWithTriple(variant))
149+
assert(variant.isMacOSX)
150+
commandLine.appendFlag("-macosx_version_min")
151+
commandLine.appendFlag(variant.version().description)
152+
} else {
153+
assert(targetTriple.isValidForZipperingWithTriple(variant))
154+
assert(variant.isMacCatalyst)
155+
commandLine.appendFlag("-maccatalyst_version_min")
156+
commandLine.appendFlag(variant.version().description)
157+
}
158+
}
142159
}
143160

144161
private func addArgsToLinkARCLite(
@@ -179,7 +196,8 @@ extension DarwinToolchain {
179196
outputFile: VirtualPath,
180197
sdkPath: String?,
181198
sanitizers: Set<Sanitizer>,
182-
targetTriple: Triple
199+
targetTriple: Triple,
200+
targetVariantTriple: Triple?
183201
) throws -> AbsolutePath {
184202

185203
// FIXME: If we used Clang as a linker instead of going straight to ld,
@@ -263,7 +281,8 @@ extension DarwinToolchain {
263281
)
264282
addDeploymentTargetArgs(
265283
to: &commandLine,
266-
targetTriple: targetTriple
284+
targetTriple: targetTriple,
285+
targetVariantTriple: targetVariantTriple
267286
)
268287
try addProfileGenerationArgs(
269288
to: &commandLine,

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ extension Driver {
5454
}
5555
}
5656

57+
if let variant = parsedOptions.getLastArgument(.targetVariant)?.asSingle {
58+
commandLine.appendFlag(.targetVariant)
59+
commandLine.appendFlag(Triple(variant, normalizing: true).triple)
60+
}
61+
5762
// Enable address top-byte ignored in the ARM64 backend.
5863
if (targetTriple.arch == .aarch64) {
5964
commandLine.appendFlag(.Xllvm)

Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ extension GenericUnixToolchain {
5151
outputFile: VirtualPath,
5252
sdkPath: String?,
5353
sanitizers: Set<Sanitizer>,
54-
targetTriple: Triple
54+
targetTriple: Triple,
55+
targetVariantTriple: Triple?
5556
) throws -> AbsolutePath {
5657
switch linkerOutputType {
5758
case .dynamicLibrary:

Sources/SwiftDriver/Jobs/LinkJob.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ extension Driver {
4848
outputFile: outputFile,
4949
sdkPath: sdkPath,
5050
sanitizers: enabledSanitizers,
51-
targetTriple: targetTriple
51+
targetTriple: targetTriple,
52+
targetVariantTriple: targetVariantTriple
5253
)
5354

5455
// TODO: some, but not all, linkers support response files.

Sources/SwiftDriver/Jobs/Planning.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ extension Driver {
172172
var commandLine: [Job.ArgTemplate] = [.flag("-frontend"),
173173
.flag("-print-target-info")]
174174
try commandLine.appendLast(.target, from: &parsedOptions)
175+
try commandLine.appendLast(.targetVariant, from: &parsedOptions)
175176
try commandLine.appendLast(.sdk, from: &parsedOptions)
176177
try commandLine.appendLast(.resourceDir, from: &parsedOptions)
177178
return Job(kind: .printTargetInfo,

Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ extension Toolchain {
3838
return resourceDirBase.appending(components: triple.platformName() ?? "")
3939
}
4040

41+
func computeSecondaryResourceDirPath(for triple: Triple, primaryPath: AbsolutePath) -> AbsolutePath? {
42+
guard triple.isMacCatalyst else { return nil }
43+
return primaryPath.parentDirectory.appending(component: "macosx")
44+
}
45+
4146
func clangLibraryPath(
4247
for triple: Triple,
4348
parsedOptions: inout ParsedOptions
@@ -56,13 +61,25 @@ extension Toolchain {
5661
sdkPath: String?,
5762
isShared: Bool
5863
) throws -> [AbsolutePath] {
59-
var result = [try computeResourceDirPath(
64+
let resourceDirPath = try computeResourceDirPath(
6065
for: triple,
6166
parsedOptions: &parsedOptions,
62-
isShared: isShared)]
67+
isShared: isShared)
68+
var result = [resourceDirPath]
69+
70+
let secondaryResourceDir = computeSecondaryResourceDirPath(for: triple, primaryPath: resourceDirPath)
71+
if let path = secondaryResourceDir {
72+
result.append(path)
73+
}
6374

6475
if let path = sdkPath {
65-
result.append(AbsolutePath(path).appending(RelativePath("usr/lib/swift")))
76+
let sdkPath = AbsolutePath(path)
77+
// If we added the secondary resource dir, we also need the iOSSupport directory.
78+
if secondaryResourceDir != nil {
79+
result.append(sdkPath.appending(components: "System", "iOSSupport", "usr", "lib", "swift"))
80+
}
81+
82+
result.append(sdkPath.appending(RelativePath("usr/lib/swift")))
6683
}
6784

6885
return result

Sources/SwiftDriver/Toolchains/Toolchain.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ public protocol Toolchain {
5858
outputFile: VirtualPath,
5959
sdkPath: String?,
6060
sanitizers: Set<Sanitizer>,
61-
targetTriple: Triple
61+
targetTriple: Triple,
62+
targetVariantTriple: Triple?
6263
) throws -> AbsolutePath
6364

6465
func runtimeLibraryName(

Sources/SwiftDriver/Utilities/Triple+Platforms.swift

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ public enum DarwinPlatform: Hashable {
2727
case iOS(Environment)
2828

2929
/// tvOS, corresponding to the `tvos` OS name.
30-
case tvOS(Environment)
30+
case tvOS(EnvironmentWithoutCatalyst)
3131

3232
/// watchOS, corresponding to the `watchos` OS name.
33-
case watchOS(Environment)
33+
case watchOS(EnvironmentWithoutCatalyst)
3434

3535
/// The most general form of environment information attached to a
3636
/// `DarwinPlatform`.
@@ -39,9 +39,23 @@ public enum DarwinPlatform: Hashable {
3939
/// Not all platforms support all values of environment. This type is a superset of
4040
/// all the environments available on any case.
4141
public enum Environment: Hashable {
42-
// FIXME: iOS should also have a state for macCatalyst. We should
43-
// probably have an EnvironmentWithoutCatalyst type for tvOS and
44-
// watchOS to use and mechanisms to convert between them.
42+
case device
43+
case simulator
44+
case catalyst
45+
46+
var withoutCatalyst: EnvironmentWithoutCatalyst? {
47+
switch self {
48+
case .device:
49+
return .device
50+
case .simulator:
51+
return .simulator
52+
case .catalyst:
53+
return nil
54+
}
55+
}
56+
}
57+
58+
public enum EnvironmentWithoutCatalyst: Hashable {
4559
case device
4660
case simulator
4761
}
@@ -57,9 +71,11 @@ public enum DarwinPlatform: Hashable {
5771
case .iOS:
5872
return .iOS(environment)
5973
case .tvOS:
60-
return .tvOS(environment)
74+
guard let withoutCatalyst = environment.withoutCatalyst else { return nil }
75+
return .tvOS(withoutCatalyst)
6176
case .watchOS:
62-
return .watchOS(environment)
77+
guard let withoutCatalyst = environment.withoutCatalyst else { return nil }
78+
return .watchOS(withoutCatalyst)
6379
}
6480
}
6581

@@ -73,6 +89,8 @@ public enum DarwinPlatform: Hashable {
7389
return "iphoneos"
7490
case .iOS(.simulator):
7591
return "iphonesimulator"
92+
case .iOS(.catalyst):
93+
return "maccatalyst"
7694
case .tvOS(.device):
7795
return "appletvos"
7896
case .tvOS(.simulator):
@@ -93,6 +111,8 @@ public enum DarwinPlatform: Hashable {
93111
return "ios"
94112
case .iOS(.simulator):
95113
return "iossim"
114+
case .iOS(.catalyst):
115+
return "osx"
96116
case .tvOS(.device):
97117
return "tvos"
98118
case .tvOS(.simulator):
@@ -143,14 +163,20 @@ extension Triple {
143163
///
144164
/// - SeeAlso: DarwinPlatform
145165
public var darwinPlatform: DarwinPlatform? {
146-
func makeEnvironment() -> DarwinPlatform.Environment {
166+
func makeEnvironment() -> DarwinPlatform.EnvironmentWithoutCatalyst {
147167
_isSimulatorEnvironment ? .simulator : .device
148168
}
149169
switch os {
150170
case .darwin, .macosx:
151171
return .macOS
152172
case .ios:
153-
return .iOS(makeEnvironment())
173+
if isMacCatalyst {
174+
return .iOS(.catalyst)
175+
} else if _isSimulatorEnvironment {
176+
return .iOS(.simulator)
177+
} else {
178+
return .iOS(.device)
179+
}
154180
case .watchos:
155181
return .watchOS(makeEnvironment())
156182
case .tvos:

Sources/SwiftDriver/Utilities/Triple.swift

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,7 @@ extension Triple {
12271227
}
12281228
}
12291229

1230-
public enum Environment: String, CaseIterable {
1230+
public enum Environment: String, CaseIterable, Equatable {
12311231
case eabihf
12321232
case eabi
12331233
case elfv1
@@ -1628,6 +1628,39 @@ extension Triple {
16281628
}
16291629
}
16301630

1631+
// MARK: - Catalyst
1632+
1633+
extension Triple {
1634+
var isMacCatalyst: Bool {
1635+
return self.isiOS && !self.isTvOS && environment == .macabi
1636+
}
1637+
1638+
func isValidForZipperingWithTriple(_ variant: Triple) -> Bool {
1639+
guard archName == variant.archName,
1640+
arch == variant.arch,
1641+
subArch == variant.subArch,
1642+
vendor == variant.vendor else {
1643+
return false
1644+
}
1645+
1646+
// Allow a macOS target and an iOS-macabi target variant
1647+
// This is typically the case when zippering a library originally
1648+
// developed for macOS.
1649+
if self.isMacOSX && variant.isMacCatalyst {
1650+
return true
1651+
}
1652+
1653+
// Allow an iOS-macabi target and a macOS target variant. This would
1654+
// be the case when zippering a library originally developed for
1655+
// iOS.
1656+
if variant.isMacOSX && isMacCatalyst {
1657+
return true
1658+
}
1659+
1660+
return false
1661+
}
1662+
}
1663+
16311664
fileprivate extension Array {
16321665

16331666
mutating func resize(toCount desiredCount: Int, paddingWith element: Element) {

0 commit comments

Comments
 (0)