diff --git a/Sources/SwiftDriver/Driver/Driver.swift b/Sources/SwiftDriver/Driver/Driver.swift index 7f298fdc1..88360d06b 100644 --- a/Sources/SwiftDriver/Driver/Driver.swift +++ b/Sources/SwiftDriver/Driver/Driver.swift @@ -603,6 +603,7 @@ public struct Driver { try toolchain.validateArgs(&parsedOptions, targetTriple: self.frontendTargetInfo.target.triple, targetVariantTriple: self.frontendTargetInfo.targetVariant?.triple, + compilerOutputType: self.compilerOutputType, diagnosticsEngine: diagnosticEngine) // Compute debug information output. diff --git a/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift b/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift index c57b6cf8a..f95fffe56 100644 --- a/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift +++ b/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift @@ -143,7 +143,7 @@ public final class DarwinToolchain: Toolchain { public enum ToolchainValidationError: Error, DiagnosticData { case osVersionBelowMinimumDeploymentTarget(String) case argumentNotSupported(String) - case iOSVersionAboveMaximumDeploymentTarget(Int) + case invalidDeploymentTargetForIR(String, String) case unsupportedTargetVariant(variant: Triple) case darwinOnlySupportsLibCxx @@ -151,8 +151,9 @@ public final class DarwinToolchain: Toolchain { switch self { case .osVersionBelowMinimumDeploymentTarget(let target): return "Swift requires a minimum deployment target of \(target)" - case .iOSVersionAboveMaximumDeploymentTarget(let version): - return "iOS \(version) does not support 32-bit programs" + case .invalidDeploymentTargetForIR(let target, let archName): + return + "\(target) and above does not support emitting binaries or IR for \(archName)" case .unsupportedTargetVariant(variant: let variant): return "unsupported '\(variant.isiOS ? "-target-variant" : "-target")' value '\(variant.triple)'; use 'ios-macabi' instead" case .argumentNotSupported(let argument): @@ -166,6 +167,7 @@ public final class DarwinToolchain: Toolchain { public func validateArgs(_ parsedOptions: inout ParsedOptions, targetTriple: Triple, targetVariantTriple: Triple?, + compilerOutputType: FileType?, diagnosticsEngine: DiagnosticsEngine) throws { // On non-darwin hosts, libArcLite won't be found and a warning will be emitted // Guard for the sake of tests running on all platforms @@ -176,7 +178,8 @@ public final class DarwinToolchain: Toolchain { diagnosticsEngine: diagnosticsEngine) #endif // Validating apple platforms deployment targets. - try validateDeploymentTarget(&parsedOptions, targetTriple: targetTriple) + try validateDeploymentTarget(&parsedOptions, targetTriple: targetTriple, + compilerOutputType: compilerOutputType) if let targetVariantTriple = targetVariantTriple, !targetTriple.isValidForZipperingWithTriple(targetVariantTriple) { throw ToolchainValidationError.unsupportedTargetVariant(variant: targetVariantTriple) @@ -198,7 +201,7 @@ public final class DarwinToolchain: Toolchain { } func validateDeploymentTarget(_ parsedOptions: inout ParsedOptions, - targetTriple: Triple) throws { + targetTriple: Triple, compilerOutputType: FileType?) throws { // Check minimum supported OS versions. if targetTriple.isMacOSX, targetTriple.version(for: .macOS) < Triple.Version(10, 9, 0) { @@ -213,8 +216,11 @@ public final class DarwinToolchain: Toolchain { throw ToolchainValidationError.osVersionBelowMinimumDeploymentTarget("iOS 7") } if targetTriple.arch?.is32Bit == true, - targetTriple.version(for: .iOS(.device)) >= Triple.Version(11, 0, 0) { - throw ToolchainValidationError.iOSVersionAboveMaximumDeploymentTarget(targetTriple.version(for: .iOS(.device)).major) + targetTriple.version(for: .iOS(.device)) >= Triple.Version(11, 0, 0), + compilerOutputType != .swiftModule { + throw + ToolchainValidationError + .invalidDeploymentTargetForIR("iOS 11", targetTriple.archName) } } else if targetTriple.isWatchOS, targetTriple.version(for: .watchOS(.device)) < Triple.Version(2, 0, 0) { diff --git a/Sources/SwiftDriver/Toolchains/Toolchain.swift b/Sources/SwiftDriver/Toolchains/Toolchain.swift index 8b70c5261..6b7fad345 100644 --- a/Sources/SwiftDriver/Toolchains/Toolchain.swift +++ b/Sources/SwiftDriver/Toolchains/Toolchain.swift @@ -66,7 +66,9 @@ public protocol Toolchain { /// Perform platform-specific argument validation. func validateArgs(_ parsedOptions: inout ParsedOptions, targetTriple: Triple, - targetVariantTriple: Triple?, diagnosticsEngine: DiagnosticsEngine) throws + targetVariantTriple: Triple?, + compilerOutputType: FileType?, + diagnosticsEngine: DiagnosticsEngine) throws /// Adds platform-specific linker flags to the provided command line func addPlatformSpecificLinkerArgs( @@ -214,8 +216,9 @@ extension Toolchain { } public func validateArgs(_ parsedOptions: inout ParsedOptions, - targetTriple: Triple, - targetVariantTriple: Triple?, diagnosticsEngine: DiagnosticsEngine) {} + targetTriple: Triple, targetVariantTriple: Triple?, + compilerOutputType: FileType?, + diagnosticsEngine: DiagnosticsEngine) {} public func addPlatformSpecificCommonFrontendOptions( commandLine: inout [Job.ArgTemplate], diff --git a/Sources/SwiftDriver/Toolchains/WindowsToolchain.swift b/Sources/SwiftDriver/Toolchains/WindowsToolchain.swift index 61f3fb9e7..475c52ef1 100644 --- a/Sources/SwiftDriver/Toolchains/WindowsToolchain.swift +++ b/Sources/SwiftDriver/Toolchains/WindowsToolchain.swift @@ -138,6 +138,7 @@ extension WindowsToolchain.ToolchainValidationError { public func validateArgs(_ parsedOptions: inout ParsedOptions, targetTriple: Triple, targetVariantTriple: Triple?, + compilerOutputType: FileType?, diagnosticEngine: DiagnosticsEngine) throws { // TODO(compnerd) validate any options we can } diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index 678395f01..294d29300 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -3039,6 +3039,16 @@ final class SwiftDriverTests: XCTestCase { } } + func testValidDeprecatedTargets() throws { + var driver = try Driver(args: ["swiftc", "-emit-module", "-target", "armv7-apple-ios13.0", "foo.swift"]) + let plannedJobs = try driver.planBuild() + let emitModuleJob = plannedJobs.first(where: {$0.kind == .emitModule}) + XCTAssertNotNil(emitModuleJob) + let currentJob = emitModuleJob! + XCTAssert(currentJob.commandLine.contains(.flag("-target"))) + XCTAssert(currentJob.commandLine.contains(.flag("armv7-apple-ios13.0"))) + } + func testClangTargetForExplicitModule() throws { #if os(macOS) // Check -clang-target is on by defualt when explicit module is on. @@ -3133,14 +3143,22 @@ final class SwiftDriverTests: XCTestCase { } } - XCTAssertThrowsError(try Driver(args: ["swiftc", "-c", "-target", "armv7-apple-ios12.0", + XCTAssertThrowsError(try Driver(args: ["swiftc", "-c", "-target", "armv7-apple-ios12.1", "foo.swift"])) { error in - guard case DarwinToolchain.ToolchainValidationError.iOSVersionAboveMaximumDeploymentTarget(12) = error else { + guard case DarwinToolchain.ToolchainValidationError.invalidDeploymentTargetForIR("iOS 11", "armv7") = error else { XCTFail() return } } + XCTAssertThrowsError(try Driver(args: ["swiftc", "-emit-module", "-c", "-target", + "armv7s-apple-ios12.0", "foo.swift"])) { error in + guard case DarwinToolchain.ToolchainValidationError.invalidDeploymentTargetForIR("iOS 11", "armv7s") = error else { + XCTFail() + return + } + } + XCTAssertThrowsError(try Driver(args: ["swiftc", "-c", "-target", "x86_64-apple-ios13.0", "-target-variant", "x86_64-apple-macosx10.14", "foo.swift"])) { error in