From 4d847b9fa0f0c131fcdae554017395349336e1de Mon Sep 17 00:00:00 2001 From: Cyndy Ishida Date: Tue, 25 Jan 2022 17:43:51 -0800 Subject: [PATCH] Loosen restriction for building deprecated iOS targets This patch loosens the restriction for building deprecated iOS targets to only when the user attempts to compile a binary or emit IR. This allows the compiler to continue building swift modules and interfaces for newer deployment targets. The error message is also slightly modified to allow the same message to apply to different platforms. resolves: --- Sources/SwiftDriver/Driver/Driver.swift | 1 + .../Toolchains/DarwinToolchain.swift | 20 +++++++++++------ .../SwiftDriver/Toolchains/Toolchain.swift | 9 +++++--- .../Toolchains/WindowsToolchain.swift | 1 + Tests/SwiftDriverTests/SwiftDriverTests.swift | 22 +++++++++++++++++-- 5 files changed, 41 insertions(+), 12 deletions(-) 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