Skip to content

Change Triple.isiOS to no longer match tvOS #1955

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion Sources/SwiftDriver/Toolchains/DarwinToolchain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ public final class DarwinToolchain: Toolchain {
if (targetTriple.isMacOSX && targetTriple.version(for: .macOS) < Triple.Version(10, 11, 0)) ||
(targetTriple.isiOS && targetTriple.version(
for: .iOS(targetTriple._isSimulatorEnvironment ? .simulator : .device)) < Triple.Version(9, 0, 0)) {
return 2;
return 2
}
if (targetTriple.isMacOSX && targetTriple.version(for: .macOS) < Triple.Version(15, 0, 0)) ||
(targetTriple.isiOS && targetTriple.version(
Expand Down
18 changes: 14 additions & 4 deletions Sources/SwiftDriver/Utilities/Triple+Platforms.swift
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,10 @@ extension Triple {
switch compatibilityPlatform ?? darwinPlatform! {
case .macOS:
return _macOSVersion ?? osVersion
case .iOS, .tvOS:
case .iOS:
return _iOSVersion
case .tvOS:
return _tvOSVersion
case .watchOS:
return _watchOSVersion
case .visionOS:
Expand Down Expand Up @@ -282,22 +284,30 @@ extension Triple {
}

return _iOSVersion
case .iOS(.device), .iOS(.simulator), .tvOS(_):
// The first deployment of arm64 simulators is iOS/tvOS 14.0;
case .iOS(_):
// The first deployment of arm64 simulators is iOS 14.0;
// the linker doesn't want to see a deployment target before that.
if _isSimulatorEnvironment && _iOSVersion.major < 14 && arch == .aarch64 {
return Version(14, 0, 0)
}

return _iOSVersion
case .tvOS(_):
// The first deployment of arm64 simulators is tvOS 14.0;
// the linker doesn't want to see a deployment target before that.
if _isSimulatorEnvironment && _tvOSVersion.major < 14 && arch == .aarch64 {
return Version(14, 0, 0)
}

return _tvOSVersion
case .watchOS(_):
// The first deployment of arm64 simulators is watchOS 7;
// the linker doesn't want to see a deployment target before that.
if _isSimulatorEnvironment && osVersion.major < 7 && arch == .aarch64 {
return Version(7, 0, 0)
}

return osVersion
return _watchOSVersion
case .visionOS(_):
return _visionOSVersion
}
Expand Down
50 changes: 38 additions & 12 deletions Sources/SwiftDriver/Utilities/Triple.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1473,19 +1473,16 @@ extension Triple.OS {
self == .aix
}

/// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both
/// "darwin" and "osx" as OS X triples.
/// Is this an Apple macOS triple.
/// - note: For legacy reasons, we support both "darwin" and "macosx" as macOS triples.
public var isMacOSX: Bool {
self == .darwin || self == .macosx
}

/// Is this an iOS triple.
/// Note: This identifies tvOS as a variant of iOS. If that ever
/// changes, i.e., if the two operating systems diverge or their version
/// numbers get out of sync, that will need to be changed.
/// watchOS has completely different version numbers so it is not included.
/// Is this an Apple iOS triple.
/// - note: Contrary to historical behavior with regard to LLVM's Triple type, this does NOT match tvOS in order to avoid confusion moving forward.
public var isiOS: Bool {
self == .ios || isTvOS
self == .ios
}

/// Is this an Apple tvOS triple.
Expand All @@ -1498,14 +1495,15 @@ extension Triple.OS {
self == .watchos
}

/// Is this an Apple visionOS triple.
public var isVisionOS: Bool {
self == .visionos
}


/// isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
/// isOSDarwin - Is this a "Darwin" OS (macOS, iOS, tvOS, watchOS, or visionOS).
public var isDarwin: Bool {
isMacOSX || isiOS || isWatchOS || isVisionOS
isMacOSX || isiOS || isTvOS || isWatchOS || isVisionOS
}
}

Expand Down Expand Up @@ -1640,13 +1638,15 @@ extension Triple {
// toolchain that wants to know the iOS version number even when targeting
// OS X.
return Version(5, 0, 0)
case .ios, .tvos:
case .ios:
var version = self.osVersion
// Default to 5.0 (or 7.0 for arm64).
if version.major == 0 {
version.major = arch == .aarch64 ? 7 : 5
}
return version
case .tvos:
return osVersion
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this become fatalError("conflicting triple info") like .watchos?

case .visionos:
return Version(15, 0, 0)
case .watchos:
Expand All @@ -1656,6 +1656,32 @@ extension Triple {
}
}

/// Parse the version number as with getOSVersion. This should
/// only be called with tvOS or generic triples.
///
/// This accessor is semi-private; it's typically better to use `version(for:)` or
/// `Triple.FeatureAvailability`.
public var _tvOSVersion: Version {
Copy link
Contributor Author

@jakepetroules jakepetroules Jul 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part (and changes to _iOSVersion) could use extra scrutiny, I'm not super clear what the true intent is here in terms of what's supposed to be able to map to what.

switch os {
case .darwin, .macosx:
// Ignore the version from the triple. This is only handled because the
// the clang driver combines OS X and iOS support into a common Darwin
// toolchain that wants to know the iOS version number even when targeting
// OS X.
return Version(9, 0, 0)
case .ios, .tvos:
var version = self.osVersion
if version.major == 0 {
version.major = 9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment for why we default to 9?

}
return version
case .watchos:
fatalError("conflicting triple info")
default:
fatalError("unexpected OS for Darwin triple")
}
}

/// Parse the version number as with getOSVersion. This should only be
/// called with WatchOS or generic triples.
///
Expand Down Expand Up @@ -1705,7 +1731,7 @@ extension Triple {

extension Triple {
@_spi(Testing) public var isMacCatalyst: Bool {
return self.isiOS && !self.isTvOS && environment == .macabi
return self.isiOS && environment == .macabi
}

func isValidForZipperingWithTriple(_ variant: Triple) -> Bool {
Expand Down
31 changes: 29 additions & 2 deletions Tests/SwiftDriverTests/TripleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1054,12 +1054,23 @@ final class TripleTests: XCTestCase {

T = Triple("x86_64-apple-ios12.0")
XCTAssertTrue(T.os?.isiOS)
XCTAssertFalse(T.os?.isTvOS)
V = T._iOSVersion
XCTAssertEqual(V?.major, 12)
XCTAssertEqual(V?.minor, 0)
XCTAssertEqual(V?.micro, 0)
XCTAssertFalse(T._isSimulatorEnvironment)
XCTAssertFalse(T.isMacCatalyst)

T = Triple("x86_64-apple-tvos12.0")
XCTAssertTrue(T.os?.isTvOS)
XCTAssertFalse(T.os?.isiOS)
V = T._tvOSVersion
XCTAssertEqual(V?.major, 12)
XCTAssertEqual(V?.minor, 0)
XCTAssertEqual(V?.micro, 0)
XCTAssertFalse(T._isSimulatorEnvironment)
XCTAssertFalse(T.isMacCatalyst)
}

func testFileFormat() {
Expand Down Expand Up @@ -1143,6 +1154,7 @@ final class TripleTests: XCTestCase {
environment: T,
macOSVersion: Triple.Version?,
iOSVersion: Triple.Version?,
tvOSVersion: Triple.Version?,
watchOSVersion: Triple.Version?,
shouldHaveJetPacks: Bool,
file: StaticString = #file, line: UInt = #line
Expand Down Expand Up @@ -1170,9 +1182,11 @@ final class TripleTests: XCTestCase {
"iOS device version", file: file, line: line)
XCTAssertEqual(triple.version(for: .iOS(.simulator)), iOSVersion,
"iOS simulator version", file: file, line: line)
XCTAssertEqual(triple.version(for: .tvOS(.device)), iOSVersion,
}
if let tvOSVersion = tvOSVersion {
XCTAssertEqual(triple.version(for: .tvOS(.device)), tvOSVersion,
"tvOS device version", file: file, line: line)
XCTAssertEqual(triple.version(for: .tvOS(.simulator)), iOSVersion,
XCTAssertEqual(triple.version(for: .tvOS(.simulator)), tvOSVersion,
"tvOS simulator version", file: file, line: line)
}
if let watchOSVersion = watchOSVersion {
Expand Down Expand Up @@ -1214,27 +1228,31 @@ final class TripleTests: XCTestCase {
environment: .device,
macOSVersion: .init(10, 12, 0),
iOSVersion: .init(5, 0, 0),
tvOSVersion: .init(9, 0, 0),
watchOSVersion: .init(2, 0, 0),
shouldHaveJetPacks: false)
assertDarwinPlatformCorrect(macOS2,
case: macOS,
environment: .device,
macOSVersion: .init(10, 50, 0),
iOSVersion: .init(5, 0, 0),
tvOSVersion: .init(9, 0, 0),
watchOSVersion: .init(2, 0, 0),
shouldHaveJetPacks: true)
assertDarwinPlatformCorrect(macOS3,
case: macOS,
environment: .device,
macOSVersion: .init(10, 60, 9),
iOSVersion: .init(5, 0, 0),
tvOSVersion: .init(9, 0, 0),
watchOSVersion: .init(2, 0, 0),
shouldHaveJetPacks: true)
assertDarwinPlatformCorrect(macOS4,
case: macOS,
environment: .device,
macOSVersion: .init(10, 15, 0),
iOSVersion: .init(5, 0, 0),
tvOSVersion: .init(9, 0, 0),
watchOSVersion: .init(2, 0, 0),
shouldHaveJetPacks: false)

Expand All @@ -1247,20 +1265,23 @@ final class TripleTests: XCTestCase {
environment: .simulator,
macOSVersion: .init(10, 4, 0),
iOSVersion: .init(13, 0, 0),
tvOSVersion: nil,
watchOSVersion: nil,
shouldHaveJetPacks: false)
assertDarwinPlatformCorrect(iOS2,
case: iOS,
environment: .device,
macOSVersion: .init(10, 4, 0),
iOSVersion: .init(50, 0, 0),
tvOSVersion: nil,
watchOSVersion: nil,
shouldHaveJetPacks: true)
assertDarwinPlatformCorrect(iOS3,
case: iOS,
environment: .catalyst,
macOSVersion: .init(10, 4, 0),
iOSVersion: .init(60, 0, 0),
tvOSVersion: nil,
watchOSVersion: nil,
shouldHaveJetPacks: true)

Expand All @@ -1273,20 +1294,23 @@ final class TripleTests: XCTestCase {
environment: .simulator,
macOSVersion: .init(10, 4, 0),
iOSVersion: .init(13, 0, 0),
tvOSVersion: .init(13, 0, 0),
watchOSVersion: nil,
shouldHaveJetPacks: false)
assertDarwinPlatformCorrect(tvOS2,
case: tvOS,
environment: .device,
macOSVersion: .init(10, 4, 0),
iOSVersion: .init(50, 0, 0),
tvOSVersion: .init(50, 0, 0),
watchOSVersion: nil,
shouldHaveJetPacks: true)
assertDarwinPlatformCorrect(tvOS3,
case: tvOS,
environment: .simulator,
macOSVersion: .init(10, 4, 0),
iOSVersion: .init(60, 0, 0),
tvOSVersion: .init(60, 0, 0),
watchOSVersion: nil,
shouldHaveJetPacks: true)

Expand All @@ -1299,20 +1323,23 @@ final class TripleTests: XCTestCase {
environment: .simulator,
macOSVersion: .init(10, 4, 0),
iOSVersion: nil,
tvOSVersion: nil,
watchOSVersion: .init(6, 0, 0),
shouldHaveJetPacks: false)
assertDarwinPlatformCorrect(watchOS2,
case: watchOS,
environment: .device,
macOSVersion: .init(10, 4, 0),
iOSVersion: nil,
tvOSVersion: nil,
watchOSVersion: .init(50, 0, 0),
shouldHaveJetPacks: true)
assertDarwinPlatformCorrect(watchOS3,
case: watchOS,
environment: .simulator,
macOSVersion: .init(10, 4, 0),
iOSVersion: nil,
tvOSVersion: nil,
watchOSVersion: .init(60, 0, 0),
shouldHaveJetPacks: true)
}
Expand Down