Skip to content

Add support for catalyst #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Sources/SwiftDriver/Driver/Driver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ public struct Driver {
/// The target triple.
public let targetTriple: Triple

/// The variant target triple.
public let targetVariantTriple: Triple?

/// The toolchain to use for resolution.
public let toolchain: Toolchain

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

// Find the Swift compiler executable.
if let frontendPath = self.parsedOptions.getLastArgument(.driverUseFrontendPath) {
Expand Down
25 changes: 22 additions & 3 deletions Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ extension DarwinToolchain {

private func addDeploymentTargetArgs(
to commandLine: inout [Job.ArgTemplate],
targetTriple: Triple
targetTriple: Triple,
targetVariantTriple: Triple?
) {
// FIXME: Properly handle deployment targets.

Expand All @@ -125,6 +126,8 @@ extension DarwinToolchain {
flag = "-iphoneos_version_min"
case .iOS(.simulator):
flag = "-ios_simulator_version_min"
case .iOS(.catalyst):
flag = "-maccatalyst_version_min"
case .macOS:
flag = "-macosx_version_min"
case .tvOS(.device):
Expand All @@ -139,6 +142,20 @@ extension DarwinToolchain {

commandLine.appendFlag(flag)
commandLine.appendFlag(targetTriple.version().description)

if let variant = targetVariantTriple {
if targetTriple.isiOS {
assert(targetTriple.isValidForZipperingWithTriple(variant))
assert(variant.isMacOSX)
commandLine.appendFlag("-macosx_version_min")
commandLine.appendFlag(variant.version().description)
} else {
assert(targetTriple.isValidForZipperingWithTriple(variant))
assert(variant.isMacCatalyst)
commandLine.appendFlag("-maccatalyst_version_min")
commandLine.appendFlag(variant.version().description)
}
}
}

private func addArgsToLinkARCLite(
Expand Down Expand Up @@ -179,7 +196,8 @@ extension DarwinToolchain {
outputFile: VirtualPath,
sdkPath: String?,
sanitizers: Set<Sanitizer>,
targetTriple: Triple
targetTriple: Triple,
targetVariantTriple: Triple?
) throws -> AbsolutePath {

// FIXME: If we used Clang as a linker instead of going straight to ld,
Expand Down Expand Up @@ -263,7 +281,8 @@ extension DarwinToolchain {
)
addDeploymentTargetArgs(
to: &commandLine,
targetTriple: targetTriple
targetTriple: targetTriple,
targetVariantTriple: targetVariantTriple
)
try addProfileGenerationArgs(
to: &commandLine,
Expand Down
5 changes: 5 additions & 0 deletions Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ extension Driver {
}
}

if let variant = parsedOptions.getLastArgument(.targetVariant)?.asSingle {
commandLine.appendFlag(.targetVariant)
commandLine.appendFlag(Triple(variant, normalizing: true).triple)
}

// Enable address top-byte ignored in the ARM64 backend.
if (targetTriple.arch == .aarch64) {
commandLine.appendFlag(.Xllvm)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ extension GenericUnixToolchain {
outputFile: VirtualPath,
sdkPath: String?,
sanitizers: Set<Sanitizer>,
targetTriple: Triple
targetTriple: Triple,
targetVariantTriple: Triple?
) throws -> AbsolutePath {
switch linkerOutputType {
case .dynamicLibrary:
Expand Down
3 changes: 2 additions & 1 deletion Sources/SwiftDriver/Jobs/LinkJob.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ extension Driver {
outputFile: outputFile,
sdkPath: sdkPath,
sanitizers: enabledSanitizers,
targetTriple: targetTriple
targetTriple: targetTriple,
targetVariantTriple: targetVariantTriple
)

// TODO: some, but not all, linkers support response files.
Expand Down
1 change: 1 addition & 0 deletions Sources/SwiftDriver/Jobs/Planning.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ extension Driver {
var commandLine: [Job.ArgTemplate] = [.flag("-frontend"),
.flag("-print-target-info")]
try commandLine.appendLast(.target, from: &parsedOptions)
try commandLine.appendLast(.targetVariant, from: &parsedOptions)
try commandLine.appendLast(.sdk, from: &parsedOptions)
try commandLine.appendLast(.resourceDir, from: &parsedOptions)
return Job(kind: .printTargetInfo,
Expand Down
23 changes: 20 additions & 3 deletions Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ extension Toolchain {
return resourceDirBase.appending(components: triple.platformName() ?? "")
}

func computeSecondaryResourceDirPath(for triple: Triple, primaryPath: AbsolutePath) -> AbsolutePath? {
guard triple.isMacCatalyst else { return nil }
return primaryPath.parentDirectory.appending(component: "macosx")
}

func clangLibraryPath(
for triple: Triple,
parsedOptions: inout ParsedOptions
Expand All @@ -56,13 +61,25 @@ extension Toolchain {
sdkPath: String?,
isShared: Bool
) throws -> [AbsolutePath] {
var result = [try computeResourceDirPath(
let resourceDirPath = try computeResourceDirPath(
for: triple,
parsedOptions: &parsedOptions,
isShared: isShared)]
isShared: isShared)
var result = [resourceDirPath]

let secondaryResourceDir = computeSecondaryResourceDirPath(for: triple, primaryPath: resourceDirPath)
if let path = secondaryResourceDir {
result.append(path)
}

if let path = sdkPath {
result.append(AbsolutePath(path).appending(RelativePath("usr/lib/swift")))
let sdkPath = AbsolutePath(path)
// If we added the secondary resource dir, we also need the iOSSupport directory.
if secondaryResourceDir != nil {
result.append(sdkPath.appending(components: "System", "iOSSupport", "usr", "lib", "swift"))
}

result.append(sdkPath.appending(RelativePath("usr/lib/swift")))
}

return result
Expand Down
3 changes: 2 additions & 1 deletion Sources/SwiftDriver/Toolchains/Toolchain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ public protocol Toolchain {
outputFile: VirtualPath,
sdkPath: String?,
sanitizers: Set<Sanitizer>,
targetTriple: Triple
targetTriple: Triple,
targetVariantTriple: Triple?
) throws -> AbsolutePath

func runtimeLibraryName(
Expand Down
44 changes: 35 additions & 9 deletions Sources/SwiftDriver/Utilities/Triple+Platforms.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ public enum DarwinPlatform: Hashable {
case iOS(Environment)

/// tvOS, corresponding to the `tvos` OS name.
case tvOS(Environment)
case tvOS(EnvironmentWithoutCatalyst)

/// watchOS, corresponding to the `watchos` OS name.
case watchOS(Environment)
case watchOS(EnvironmentWithoutCatalyst)

/// The most general form of environment information attached to a
/// `DarwinPlatform`.
Expand All @@ -39,9 +39,23 @@ public enum DarwinPlatform: Hashable {
/// Not all platforms support all values of environment. This type is a superset of
/// all the environments available on any case.
public enum Environment: Hashable {
// FIXME: iOS should also have a state for macCatalyst. We should
// probably have an EnvironmentWithoutCatalyst type for tvOS and
// watchOS to use and mechanisms to convert between them.
case device
case simulator
case catalyst

var withoutCatalyst: EnvironmentWithoutCatalyst? {
switch self {
case .device:
return .device
case .simulator:
return .simulator
case .catalyst:
return nil
}
}
}

public enum EnvironmentWithoutCatalyst: Hashable {
case device
case simulator
}
Expand All @@ -57,9 +71,11 @@ public enum DarwinPlatform: Hashable {
case .iOS:
return .iOS(environment)
case .tvOS:
return .tvOS(environment)
guard let withoutCatalyst = environment.withoutCatalyst else { return nil }
return .tvOS(withoutCatalyst)
case .watchOS:
return .watchOS(environment)
guard let withoutCatalyst = environment.withoutCatalyst else { return nil }
return .watchOS(withoutCatalyst)
}
}

Expand All @@ -73,6 +89,8 @@ public enum DarwinPlatform: Hashable {
return "iphoneos"
case .iOS(.simulator):
return "iphonesimulator"
case .iOS(.catalyst):
return "maccatalyst"
case .tvOS(.device):
return "appletvos"
case .tvOS(.simulator):
Expand All @@ -93,6 +111,8 @@ public enum DarwinPlatform: Hashable {
return "ios"
case .iOS(.simulator):
return "iossim"
case .iOS(.catalyst):
return "osx"
case .tvOS(.device):
return "tvos"
case .tvOS(.simulator):
Expand Down Expand Up @@ -143,14 +163,20 @@ extension Triple {
///
/// - SeeAlso: DarwinPlatform
public var darwinPlatform: DarwinPlatform? {
func makeEnvironment() -> DarwinPlatform.Environment {
func makeEnvironment() -> DarwinPlatform.EnvironmentWithoutCatalyst {
_isSimulatorEnvironment ? .simulator : .device
}
switch os {
case .darwin, .macosx:
return .macOS
case .ios:
return .iOS(makeEnvironment())
if isMacCatalyst {
return .iOS(.catalyst)
} else if _isSimulatorEnvironment {
return .iOS(.simulator)
} else {
return .iOS(.device)
}
case .watchos:
return .watchOS(makeEnvironment())
case .tvos:
Expand Down
35 changes: 34 additions & 1 deletion Sources/SwiftDriver/Utilities/Triple.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1227,7 +1227,7 @@ extension Triple {
}
}

public enum Environment: String, CaseIterable {
public enum Environment: String, CaseIterable, Equatable {
case eabihf
case eabi
case elfv1
Expand Down Expand Up @@ -1628,6 +1628,39 @@ extension Triple {
}
}

// MARK: - Catalyst

extension Triple {
var isMacCatalyst: Bool {
return self.isiOS && !self.isTvOS && environment == .macabi
}

func isValidForZipperingWithTriple(_ variant: Triple) -> Bool {
guard archName == variant.archName,
arch == variant.arch,
subArch == variant.subArch,
vendor == variant.vendor else {
return false
}

// Allow a macOS target and an iOS-macabi target variant
// This is typically the case when zippering a library originally
// developed for macOS.
if self.isMacOSX && variant.isMacCatalyst {
return true
}

// Allow an iOS-macabi target and a macOS target variant. This would
// be the case when zippering a library originally developed for
// iOS.
if variant.isMacOSX && isMacCatalyst {
return true
}

return false
}
}

fileprivate extension Array {

mutating func resize(toCount desiredCount: Int, paddingWith element: Element) {
Expand Down
Loading