Skip to content

Commit 678f654

Browse files
authored
Merge pull request #606 from artemcm/SDKTooOld
Attempt to diagnose arguments to `-sdk` that point to unsupported SDKs
2 parents c042fab + 649aef9 commit 678f654

File tree

26 files changed

+224
-6
lines changed

26 files changed

+224
-6
lines changed

Sources/SwiftDriver/Driver/Driver.swift

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

20242024
if !fileSystem.exists(path) {
20252025
diagnosticsEngine.emit(.warning_no_such_sdk(sdkPath))
2026+
} else if isSDKTooOld(sdkPath: path, fileSystem: fileSystem,
2027+
diagnosticsEngine: diagnosticsEngine) {
2028+
diagnosticsEngine.emit(.error_sdk_too_old(sdkPath))
2029+
return nil
20262030
}
2027-
// .. else check if SDK is too old (we need target triple to diagnose that).
20282031

20292032
return .absolute(path)
20302033
}
@@ -2033,6 +2036,32 @@ extension Driver {
20332036
}
20342037
}
20352038

2039+
// SDK checking: attempt to diagnose if the SDK we are pointed at is too old.
2040+
extension Driver {
2041+
static func isSDKTooOld(sdkPath: AbsolutePath, fileSystem: FileSystem,
2042+
diagnosticsEngine: DiagnosticsEngine) -> Bool {
2043+
let sdkInfo = DarwinToolchain.readSDKInfo(fileSystem, VirtualPath.absolute(sdkPath).intern())
2044+
guard let sdkInfo = sdkInfo else {
2045+
diagnosticsEngine.emit(.warning_no_sdksettings_json(sdkPath.pathString))
2046+
return false
2047+
}
2048+
guard let sdkVersion = Version(potentiallyIncompleteVersionString: sdkInfo.versionString) else {
2049+
diagnosticsEngine.emit(.warning_fail_parse_sdk_ver(sdkInfo.versionString, sdkPath.pathString))
2050+
return false
2051+
}
2052+
if sdkInfo.canonicalName.hasPrefix("macos") {
2053+
return sdkVersion < Version(10, 15, 0)
2054+
} else if sdkInfo.canonicalName.hasPrefix("iphoneos") ||
2055+
sdkInfo.canonicalName.hasPrefix("appletvos") {
2056+
return sdkVersion < Version(13, 0, 0)
2057+
} else if sdkInfo.canonicalName.hasPrefix("watchos") {
2058+
return sdkVersion < Version(6, 0, 0)
2059+
} else {
2060+
return false
2061+
}
2062+
}
2063+
}
2064+
20362065
// Imported Objective-C header.
20372066
extension Driver {
20382067
/// Compute the path of the imported Objective-C header.

Sources/SwiftDriver/Jobs/PrebuiltModulesJob.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,11 @@ public struct SDKPrebuiltModuleInputsCollector {
135135
let canonicalName = sdkInfo.canonicalName
136136
func extractVersion(_ platform: String) -> Substring? {
137137
if canonicalName.starts(with: platform) {
138-
return canonicalName.suffix(from: canonicalName.index(canonicalName.startIndex,
139-
offsetBy: platform.count))
138+
let versionStartIndex = canonicalName.index(canonicalName.startIndex,
139+
offsetBy: platform.count)
140+
let delimiterRange = canonicalName.range(of: "internal", options: .backwards)
141+
let versionEndIndex = delimiterRange == nil ? canonicalName.endIndex : delimiterRange!.lowerBound
142+
return canonicalName[versionStartIndex..<versionEndIndex]
140143
}
141144
return nil
142145
}

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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"Version": "13.00",
3+
"CanonicalName": "iphoneos13.0"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"Version": "12.99",
3+
"CanonicalName": "iphoneos12.99"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"Version": "13.0",
3+
"CanonicalName": "iphoneos13.0"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"Version": "7.0",
3+
"CanonicalName": "iphoneos7.0"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"Version": "13.0",
3+
"CanonicalName": "appletvos13.0"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"Version": "13.0",
3+
"CanonicalName": "appletvos13.0"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"Version": "8.0",
3+
"CanonicalName": "appletvos8.0"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"Version": "7.0",
3+
"CanonicalName": "watchos7.0"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"Version": "2.0",
3+
"CanonicalName": "watchos2.0"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"Version": "3.0",
3+
"CanonicalName": "watchos3.0internal"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"Version": "3.0",
3+
"CanonicalName": "watchos3.0"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"Version": "6.0",
3+
"CanonicalName": "watchos6.0"
4+
}

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)