Skip to content

Commit 3465185

Browse files
committed
Attempt to diagnose arguments to -sdk that point to unsupported SDKs
Resolves rdar://70215624
1 parent 7bae787 commit 3465185

File tree

26 files changed

+273
-7
lines changed

26 files changed

+273
-7
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2005,8 +2005,11 @@ extension Driver {
20052005

20062006
if !fileSystem.exists(path) {
20072007
diagnosticsEngine.emit(.warning_no_such_sdk(sdkPath))
2008+
} else if isSDKTooOld(sdkPath: path, fileSystem: fileSystem,
2009+
diagnosticsEngine: diagnosticsEngine) {
2010+
diagnosticsEngine.emit(.error_sdk_too_old(sdkPath))
2011+
return nil
20082012
}
2009-
// .. else check if SDK is too old (we need target triple to diagnose that).
20102013

20112014
return .absolute(path)
20122015
}
@@ -2015,6 +2018,32 @@ extension Driver {
20152018
}
20162019
}
20172020

2021+
// SDK checking: attempt to diagnose if the SDK we are pointed at is too old.
2022+
extension Driver {
2023+
static func isSDKTooOld(sdkPath: AbsolutePath, fileSystem: FileSystem,
2024+
diagnosticsEngine: DiagnosticsEngine) -> Bool {
2025+
let sdkInfo = DarwinToolchain.readSDKInfo(fileSystem, VirtualPath.absolute(sdkPath).intern())
2026+
guard let sdkInfo = sdkInfo else {
2027+
diagnosticsEngine.emit(.warning_no_sdksettings_json(sdkPath.pathString))
2028+
return false
2029+
}
2030+
guard let sdkVersion = Version(potentiallyIncompleteVersionString: sdkInfo.versionString) else {
2031+
diagnosticsEngine.emit(.warning_fail_parse_sdk_ver(sdkInfo.versionString, sdkPath.pathString))
2032+
return false
2033+
}
2034+
if sdkInfo.canonicalName.hasPrefix("macos") {
2035+
return sdkVersion < Version(10, 15, 0)
2036+
} else if sdkInfo.canonicalName.hasPrefix("iphoneos") ||
2037+
sdkInfo.canonicalName.hasPrefix("appletvos") {
2038+
return sdkVersion < Version(13, 0, 0)
2039+
} else if sdkInfo.canonicalName.hasPrefix("watchos") {
2040+
return sdkVersion < Version(6, 0, 0)
2041+
} else {
2042+
return false
2043+
}
2044+
}
2045+
}
2046+
20182047
// Imported Objective-C header.
20192048
extension Driver {
20202049
/// Compute the path of the imported Objective-C header.

Sources/SwiftDriver/Jobs/PrebuiltModulesJob.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,11 @@ public struct SDKPrebuiltModuleInputsCollector {
117117
let canonicalName = sdkInfo.canonicalName
118118
func extractVersion(_ platform: String) -> Substring? {
119119
if canonicalName.starts(with: platform) {
120-
return canonicalName.suffix(from: canonicalName.index(canonicalName.startIndex,
121-
offsetBy: platform.count))
120+
let versionStartIndex = canonicalName.index(canonicalName.startIndex,
121+
offsetBy: platform.count)
122+
let delimiterRange = canonicalName.range(of: "internal", options: .backwards)
123+
let versionEndIndex = delimiterRange == nil ? canonicalName.endIndex : delimiterRange!.lowerBound
124+
return canonicalName[versionStartIndex..<versionEndIndex]
122125
}
123126
return nil
124127
}
@@ -138,7 +141,7 @@ public struct SDKPrebuiltModuleInputsCollector {
138141
} else if let version = extractVersion("appletvsimulator") {
139142
return "arm64-apple-tvos\(version)-simulator"
140143
} else {
141-
diagEngine.emit(error: "unhandled platform name: \(canonicalName)")
144+
diagEngine.emit(error: "unrecognized platform name: \(sdkInfo.canonicalName)")
142145
return ""
143146
}
144147
}

Sources/SwiftDriver/Utilities/Diagnostics.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,18 @@ extension Diagnostic.Message {
9393
.warning("no such SDK: \(path)")
9494
}
9595

96+
static func warning_no_sdksettings_json(_ path: String) -> Diagnostic.Message {
97+
.warning("Could not read SDKSettings.json for SDK at: \(path)")
98+
}
99+
100+
static func warning_fail_parse_sdk_ver(_ version: String, _ path: String) -> Diagnostic.Message {
101+
.warning("Could not parse SDK version '\(version)' at: \(path)")
102+
}
103+
104+
static func error_sdk_too_old(_ path: String) -> Diagnostic.Message {
105+
.error("Swift does not support the SDK \(path)")
106+
}
107+
96108
static func error_unknown_target(_ target: String) -> Diagnostic.Message {
97109
.error("unknown target '\(target)'")
98110
}

Sources/SwiftDriver/Utilities/Triple+Platforms.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ extension Triple {
171171
{
172172
switch compatibilityPlatform ?? darwinPlatform! {
173173
case .macOS:
174-
return _macOSVersion!
174+
return _macOSVersion ?? osVersion
175175
case .iOS, .tvOS:
176176
return _iOSVersion
177177
case .watchOS:
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "10.10",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "macosx10.10"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "10.11",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "macosx10.11"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "10.14",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "macosx10.14internal"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "10.15.4",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "macosx10.15.4"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "10.15",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "macosx10.15internal"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "10.15",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "macosx10.15"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "10.8",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "macosx10.8"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "10.9",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "macosx10.9"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "7.17",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "macosx7.17"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "13.00",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "iphoneos13.0"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "12.99",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "iphoneos12.99"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "13.0",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "iphoneos13.0"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "7.0",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "iphoneos7.0"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "13.0",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "appletvos13.0"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "13.0",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "appletvos13.0"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "8.0",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "appletvos8.0"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "7.0",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "watchos7.0"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "2.0",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "watchos2.0"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "3.0",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "watchos3.0internal"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "3.0",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "watchos3.0"
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Version": "6.0",
3+
"VersionMap": {
4+
"macOS_iOSMac": {},
5+
"iOSMac_macOS": {}
6+
},
7+
"CanonicalName": "watchos6.0"
8+
}

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2581,7 +2581,7 @@ final class SwiftDriverTests: XCTestCase {
25812581
// Test cases ported from Driver/macabi-environment.swift
25822582
func testDarwinSDKVersioning() throws {
25832583
try withTemporaryDirectory { tmpDir in
2584-
let sdk1 = tmpDir.appending(component: "MacOSX10.15.versioned.sdk")
2584+
let sdk1 = tmpDir.appending(component: "MacOSX10.15.sdk")
25852585
try localFileSystem.writeFileContents(sdk1.appending(component: "SDKSettings.json")) {
25862586
$0 <<< """
25872587
{
@@ -2601,7 +2601,7 @@ final class SwiftDriverTests: XCTestCase {
26012601
"""
26022602
}
26032603

2604-
let sdk2 = tmpDir.appending(component: "MacOSX10.15.4.versioned.sdk")
2604+
let sdk2 = tmpDir.appending(component: "MacOSX10.15.4.sdk")
26052605
try localFileSystem.writeFileContents(sdk2.appending(component: "SDKSettings.json")) {
26062606
$0 <<< """
26072607
{
@@ -2738,6 +2738,60 @@ final class SwiftDriverTests: XCTestCase {
27382738
}
27392739
}
27402740

2741+
func testDarwinSDKTooOld() throws {
2742+
func getSDKPath(sdkDirName: String) -> AbsolutePath {
2743+
let packageRootPath = AbsolutePath(String(URL(fileURLWithPath: #file).pathComponents
2744+
.prefix(while: { $0 != "Tests" }).joined(separator: "/").dropFirst()))
2745+
let testInputsPath = packageRootPath.appending(component: "TestInputs")
2746+
.appending(component: "SDKChecks")
2747+
return testInputsPath.appending(component: sdkDirName)
2748+
}
2749+
// Ensure an error is emitted for an unsupported SDK
2750+
func checkSDKUnsupported(sdkDirName: String)
2751+
throws {
2752+
let sdkPath = getSDKPath(sdkDirName: sdkDirName)
2753+
// Get around the check for SDK's existence
2754+
try localFileSystem.createDirectory(sdkPath)
2755+
let args = [ "swiftc", "foo.swift", "-sdk", sdkPath.pathString ]
2756+
try assertDriverDiagnostics(args: args) { driver, verifier in
2757+
verifier.expect(.error("Swift does not support the SDK \(sdkPath.pathString)"))
2758+
}
2759+
}
2760+
2761+
// Ensure no error is emitted for a supported SDK
2762+
func checkSDKOkay(sdkDirName: String) throws {
2763+
let sdkPath = getSDKPath(sdkDirName: sdkDirName)
2764+
try localFileSystem.createDirectory(sdkPath)
2765+
let args = [ "swiftc", "foo.swift", "-sdk", sdkPath.pathString ]
2766+
try assertNoDiagnostics { de in let _ = try Driver(args: args, diagnosticsEngine: de) }
2767+
}
2768+
2769+
// Ensure old/bogus SDK versions are caught
2770+
try checkSDKUnsupported(sdkDirName: "tvOS8.0.sdk")
2771+
try checkSDKUnsupported(sdkDirName: "MacOSX10.8.sdk")
2772+
try checkSDKUnsupported(sdkDirName: "MacOSX10.9.sdk")
2773+
try checkSDKUnsupported(sdkDirName: "MacOSX10.10.sdk")
2774+
try checkSDKUnsupported(sdkDirName: "MacOSX10.11.sdk")
2775+
try checkSDKUnsupported(sdkDirName: "MacOSX7.17.sdk")
2776+
try checkSDKUnsupported(sdkDirName: "MacOSX10.14.Internal.sdk")
2777+
try checkSDKUnsupported(sdkDirName: "iPhoneOS7.sdk")
2778+
try checkSDKUnsupported(sdkDirName: "iPhoneOS12.99.sdk")
2779+
try checkSDKUnsupported(sdkDirName: "watchOS2.0.sdk")
2780+
try checkSDKUnsupported(sdkDirName: "watchOS3.0.sdk")
2781+
try checkSDKUnsupported(sdkDirName: "watchOS3.0.Internal.sdk")
2782+
2783+
// Verify a selection of okay SDKs
2784+
try checkSDKOkay(sdkDirName: "MacOSX10.15.sdk")
2785+
try checkSDKOkay(sdkDirName: "MacOSX10.15.4.sdk")
2786+
try checkSDKOkay(sdkDirName: "MacOSX10.15.Internal.sdk")
2787+
try checkSDKOkay(sdkDirName: "iPhoneOS13.0.sdk")
2788+
try checkSDKOkay(sdkDirName: "tvOS13.0.sdk")
2789+
try checkSDKOkay(sdkDirName: "watchOS6.0.sdk")
2790+
try checkSDKOkay(sdkDirName: "iPhoneOS.sdk")
2791+
try checkSDKOkay(sdkDirName: "tvOS.sdk")
2792+
try checkSDKOkay(sdkDirName: "watchOS.sdk")
2793+
}
2794+
27412795
func testDarwinLinkerPlatformVersion() throws {
27422796
do {
27432797
var driver = try Driver(args: ["swiftc",

0 commit comments

Comments
 (0)