diff --git a/Sources/SwiftDriver/Driver/Driver.swift b/Sources/SwiftDriver/Driver/Driver.swift index 5112664b8..e0c26242d 100644 --- a/Sources/SwiftDriver/Driver/Driver.swift +++ b/Sources/SwiftDriver/Driver/Driver.swift @@ -77,6 +77,9 @@ public struct Driver { /// The target triple. public let targetTriple: Triple + /// The variant target triple. + public let targetVariantTriple: Triple? + /// The toolchain to use for resolution. public let toolchain: Toolchain @@ -238,6 +241,7 @@ public struct Driver { Triple($0, normalizing: true) } (self.toolchain, self.targetTriple) = try Self.computeToolchain(explicitTarget, diagnosticsEngine: diagnosticEngine, env: env) + self.targetVariantTriple = self.parsedOptions.getLastArgument(.targetVariant).map { Triple($0.asSingle, normalizing: true) } // Find the Swift compiler executable. if let frontendPath = self.parsedOptions.getLastArgument(.driverUseFrontendPath) { diff --git a/Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift b/Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift index 26a038826..4c55e2693 100644 --- a/Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift +++ b/Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift @@ -114,7 +114,8 @@ extension DarwinToolchain { private func addDeploymentTargetArgs( to commandLine: inout [Job.ArgTemplate], - targetTriple: Triple + targetTriple: Triple, + targetVariantTriple: Triple? ) { // FIXME: Properly handle deployment targets. @@ -125,6 +126,8 @@ extension DarwinToolchain { flag = "-iphoneos_version_min" case .iOS(.simulator): flag = "-ios_simulator_version_min" + case .iOS(.catalyst): + flag = "-maccatalyst_version_min" case .macOS: flag = "-macosx_version_min" case .tvOS(.device): @@ -139,6 +142,20 @@ extension DarwinToolchain { commandLine.appendFlag(flag) commandLine.appendFlag(targetTriple.version().description) + + if let variant = targetVariantTriple { + if targetTriple.isiOS { + assert(targetTriple.isValidForZipperingWithTriple(variant)) + assert(variant.isMacOSX) + commandLine.appendFlag("-macosx_version_min") + commandLine.appendFlag(variant.version().description) + } else { + assert(targetTriple.isValidForZipperingWithTriple(variant)) + assert(variant.isMacCatalyst) + commandLine.appendFlag("-maccatalyst_version_min") + commandLine.appendFlag(variant.version().description) + } + } } private func addArgsToLinkARCLite( @@ -179,7 +196,8 @@ extension DarwinToolchain { outputFile: VirtualPath, sdkPath: String?, sanitizers: Set, - targetTriple: Triple + targetTriple: Triple, + targetVariantTriple: Triple? ) throws -> AbsolutePath { // FIXME: If we used Clang as a linker instead of going straight to ld, @@ -263,7 +281,8 @@ extension DarwinToolchain { ) addDeploymentTargetArgs( to: &commandLine, - targetTriple: targetTriple + targetTriple: targetTriple, + targetVariantTriple: targetVariantTriple ) try addProfileGenerationArgs( to: &commandLine, diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index 3d7cd3cf0..f698a925a 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -54,6 +54,11 @@ extension Driver { } } + if let variant = parsedOptions.getLastArgument(.targetVariant)?.asSingle { + commandLine.appendFlag(.targetVariant) + commandLine.appendFlag(Triple(variant, normalizing: true).triple) + } + // Enable address top-byte ignored in the ARM64 backend. if (targetTriple.arch == .aarch64) { commandLine.appendFlag(.Xllvm) diff --git a/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift b/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift index e6b02ea56..f4a40fff3 100644 --- a/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift +++ b/Sources/SwiftDriver/Jobs/GenericUnixToolchain+LinkerSupport.swift @@ -51,7 +51,8 @@ extension GenericUnixToolchain { outputFile: VirtualPath, sdkPath: String?, sanitizers: Set, - targetTriple: Triple + targetTriple: Triple, + targetVariantTriple: Triple? ) throws -> AbsolutePath { switch linkerOutputType { case .dynamicLibrary: diff --git a/Sources/SwiftDriver/Jobs/LinkJob.swift b/Sources/SwiftDriver/Jobs/LinkJob.swift index 4ded747f9..970197a5e 100644 --- a/Sources/SwiftDriver/Jobs/LinkJob.swift +++ b/Sources/SwiftDriver/Jobs/LinkJob.swift @@ -48,7 +48,8 @@ extension Driver { outputFile: outputFile, sdkPath: sdkPath, sanitizers: enabledSanitizers, - targetTriple: targetTriple + targetTriple: targetTriple, + targetVariantTriple: targetVariantTriple ) // TODO: some, but not all, linkers support response files. diff --git a/Sources/SwiftDriver/Jobs/Planning.swift b/Sources/SwiftDriver/Jobs/Planning.swift index 122f1a293..b9303fb72 100644 --- a/Sources/SwiftDriver/Jobs/Planning.swift +++ b/Sources/SwiftDriver/Jobs/Planning.swift @@ -172,6 +172,7 @@ extension Driver { var commandLine: [Job.ArgTemplate] = [.flag("-frontend"), .flag("-print-target-info")] try commandLine.appendLast(.target, from: &parsedOptions) + try commandLine.appendLast(.targetVariant, from: &parsedOptions) try commandLine.appendLast(.sdk, from: &parsedOptions) try commandLine.appendLast(.resourceDir, from: &parsedOptions) return Job(kind: .printTargetInfo, diff --git a/Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift b/Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift index 31fd4774a..24621e494 100644 --- a/Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift +++ b/Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift @@ -38,6 +38,11 @@ extension Toolchain { return resourceDirBase.appending(components: triple.platformName() ?? "") } + func computeSecondaryResourceDirPath(for triple: Triple, primaryPath: AbsolutePath) -> AbsolutePath? { + guard triple.isMacCatalyst else { return nil } + return primaryPath.parentDirectory.appending(component: "macosx") + } + func clangLibraryPath( for triple: Triple, parsedOptions: inout ParsedOptions @@ -56,13 +61,25 @@ extension Toolchain { sdkPath: String?, isShared: Bool ) throws -> [AbsolutePath] { - var result = [try computeResourceDirPath( + let resourceDirPath = try computeResourceDirPath( for: triple, parsedOptions: &parsedOptions, - isShared: isShared)] + isShared: isShared) + var result = [resourceDirPath] + + let secondaryResourceDir = computeSecondaryResourceDirPath(for: triple, primaryPath: resourceDirPath) + if let path = secondaryResourceDir { + result.append(path) + } if let path = sdkPath { - result.append(AbsolutePath(path).appending(RelativePath("usr/lib/swift"))) + let sdkPath = AbsolutePath(path) + // If we added the secondary resource dir, we also need the iOSSupport directory. + if secondaryResourceDir != nil { + result.append(sdkPath.appending(components: "System", "iOSSupport", "usr", "lib", "swift")) + } + + result.append(sdkPath.appending(RelativePath("usr/lib/swift"))) } return result diff --git a/Sources/SwiftDriver/Toolchains/Toolchain.swift b/Sources/SwiftDriver/Toolchains/Toolchain.swift index fac6035c1..1650377f5 100644 --- a/Sources/SwiftDriver/Toolchains/Toolchain.swift +++ b/Sources/SwiftDriver/Toolchains/Toolchain.swift @@ -58,7 +58,8 @@ public protocol Toolchain { outputFile: VirtualPath, sdkPath: String?, sanitizers: Set, - targetTriple: Triple + targetTriple: Triple, + targetVariantTriple: Triple? ) throws -> AbsolutePath func runtimeLibraryName( diff --git a/Sources/SwiftDriver/Utilities/Triple+Platforms.swift b/Sources/SwiftDriver/Utilities/Triple+Platforms.swift index 2c493ac92..2d39b2344 100644 --- a/Sources/SwiftDriver/Utilities/Triple+Platforms.swift +++ b/Sources/SwiftDriver/Utilities/Triple+Platforms.swift @@ -27,10 +27,10 @@ public enum DarwinPlatform: Hashable { case iOS(Environment) /// tvOS, corresponding to the `tvos` OS name. - case tvOS(Environment) + case tvOS(EnvironmentWithoutCatalyst) /// watchOS, corresponding to the `watchos` OS name. - case watchOS(Environment) + case watchOS(EnvironmentWithoutCatalyst) /// The most general form of environment information attached to a /// `DarwinPlatform`. @@ -39,9 +39,23 @@ public enum DarwinPlatform: Hashable { /// Not all platforms support all values of environment. This type is a superset of /// all the environments available on any case. public enum Environment: Hashable { - // FIXME: iOS should also have a state for macCatalyst. We should - // probably have an EnvironmentWithoutCatalyst type for tvOS and - // watchOS to use and mechanisms to convert between them. + case device + case simulator + case catalyst + + var withoutCatalyst: EnvironmentWithoutCatalyst? { + switch self { + case .device: + return .device + case .simulator: + return .simulator + case .catalyst: + return nil + } + } + } + + public enum EnvironmentWithoutCatalyst: Hashable { case device case simulator } @@ -57,9 +71,11 @@ public enum DarwinPlatform: Hashable { case .iOS: return .iOS(environment) case .tvOS: - return .tvOS(environment) + guard let withoutCatalyst = environment.withoutCatalyst else { return nil } + return .tvOS(withoutCatalyst) case .watchOS: - return .watchOS(environment) + guard let withoutCatalyst = environment.withoutCatalyst else { return nil } + return .watchOS(withoutCatalyst) } } @@ -73,6 +89,8 @@ public enum DarwinPlatform: Hashable { return "iphoneos" case .iOS(.simulator): return "iphonesimulator" + case .iOS(.catalyst): + return "maccatalyst" case .tvOS(.device): return "appletvos" case .tvOS(.simulator): @@ -93,6 +111,8 @@ public enum DarwinPlatform: Hashable { return "ios" case .iOS(.simulator): return "iossim" + case .iOS(.catalyst): + return "osx" case .tvOS(.device): return "tvos" case .tvOS(.simulator): @@ -143,14 +163,20 @@ extension Triple { /// /// - SeeAlso: DarwinPlatform public var darwinPlatform: DarwinPlatform? { - func makeEnvironment() -> DarwinPlatform.Environment { + func makeEnvironment() -> DarwinPlatform.EnvironmentWithoutCatalyst { _isSimulatorEnvironment ? .simulator : .device } switch os { case .darwin, .macosx: return .macOS case .ios: - return .iOS(makeEnvironment()) + if isMacCatalyst { + return .iOS(.catalyst) + } else if _isSimulatorEnvironment { + return .iOS(.simulator) + } else { + return .iOS(.device) + } case .watchos: return .watchOS(makeEnvironment()) case .tvos: diff --git a/Sources/SwiftDriver/Utilities/Triple.swift b/Sources/SwiftDriver/Utilities/Triple.swift index 03abaf55a..39b958aab 100644 --- a/Sources/SwiftDriver/Utilities/Triple.swift +++ b/Sources/SwiftDriver/Utilities/Triple.swift @@ -1227,7 +1227,7 @@ extension Triple { } } - public enum Environment: String, CaseIterable { + public enum Environment: String, CaseIterable, Equatable { case eabihf case eabi case elfv1 @@ -1628,6 +1628,39 @@ extension Triple { } } +// MARK: - Catalyst + +extension Triple { + var isMacCatalyst: Bool { + return self.isiOS && !self.isTvOS && environment == .macabi + } + + func isValidForZipperingWithTriple(_ variant: Triple) -> Bool { + guard archName == variant.archName, + arch == variant.arch, + subArch == variant.subArch, + vendor == variant.vendor else { + return false + } + + // Allow a macOS target and an iOS-macabi target variant + // This is typically the case when zippering a library originally + // developed for macOS. + if self.isMacOSX && variant.isMacCatalyst { + return true + } + + // Allow an iOS-macabi target and a macOS target variant. This would + // be the case when zippering a library originally developed for + // iOS. + if variant.isMacOSX && isMacCatalyst { + return true + } + + return false + } +} + fileprivate extension Array { mutating func resize(toCount desiredCount: Int, paddingWith element: Element) { diff --git a/Sources/SwiftOptions/Options.swift b/Sources/SwiftOptions/Options.swift index d8f0c9836..2699c4621 100644 --- a/Sources/SwiftOptions/Options.swift +++ b/Sources/SwiftOptions/Options.swift @@ -20,7 +20,9 @@ extension Option { public static let AssumeSingleThreaded: Option = Option("-assume-single-threaded", .flag, attributes: [.helpHidden, .frontend], helpText: "Assume that code will be executed in a single-threaded environment") public static let autolinkForceLoad: Option = Option("-autolink-force-load", .flag, attributes: [.helpHidden, .frontend, .moduleInterface], helpText: "Force ld to link against this module even if no symbols are used") public static let autolinkLibrary: Option = Option("-autolink-library", .separate, attributes: [.frontend, .noDriver], helpText: "Add dependent library") + public static let avoidEmitModuleSourceInfo: Option = Option("-avoid-emit-module-source-info", .flag, attributes: [.noInteractive, .doesNotAffectIncrementalBuild], helpText: "don't emit Swift source info file") public static let buildModuleFromParseableInterface: Option = Option("-build-module-from-parseable-interface", .flag, alias: Option.compileModuleFromInterface, attributes: [.helpHidden, .frontend, .noDriver], group: .modes) + public static let buildRequestDependencyGraph: Option = Option("-build-request-dependency-graph", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Build request dependency graph") public static let bypassBatchModeChecks: Option = Option("-bypass-batch-mode-checks", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Bypass checks for batch-mode errors.") public static let checkOnoneCompleteness: Option = Option("-check-onone-completeness", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Print errors if the compile OnoneSupport module is missing symbols") public static let codeCompleteCallPatternHeuristics: Option = Option("-code-complete-call-pattern-heuristics", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Use heuristics to guess whether we want call pattern completions") @@ -63,10 +65,13 @@ extension Option { public static let disableAvailabilityChecking: Option = Option("-disable-availability-checking", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable checking for potentially unavailable APIs") public static let disableBatchMode: Option = Option("-disable-batch-mode", .flag, attributes: [.helpHidden, .frontend, .noInteractive], helpText: "Disable combining frontend jobs into batches") public static let disableBridgingPch: Option = Option("-disable-bridging-pch", .flag, attributes: [.helpHidden], helpText: "Disable automatic generation of bridging PCH files") + public static let disableClangimporterSourceImport: Option = Option("-disable-clangimporter-source-import", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable ClangImporter and forward all requests straight the DWARF importer.") public static let disableConstraintSolverPerformanceHacks: Option = Option("-disable-constraint-solver-performance-hacks", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable all the hacks in the constraint solver") public static let disableDebuggerShadowCopies: Option = Option("-disable-debugger-shadow-copies", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable debugger shadow copies of local variables.This option is only useful for testing the compiler.") public static let disableDeserializationRecovery: Option = Option("-disable-deserialization-recovery", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Don't attempt to recover from missing xrefs (etc) in swiftmodules") public static let disableDiagnosticPasses: Option = Option("-disable-diagnostic-passes", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Don't run diagnostic passes") + public static let disableFineGrainedDependencies: Option = Option("-disable-fine-grained-dependencies", .flag, attributes: [.helpHidden, .frontend], helpText: "Don't be more selective about incremental recompilation") + public static let disableGenericMetadataPrespecialization: Option = Option("-disable-generic-metadata-prespecialization", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Do not statically specialize metadata for generic types at types that are known to be used in source.") public static let disableIncrementalLlvmCodegeneration: Option = Option("-disable-incremental-llvm-codegen", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable incremental llvm code generation.") public static let disableInvalidEphemeralnessAsError: Option = Option("-disable-invalid-ephemeralness-as-error", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Diagnose invalid ephemeral to non-ephemeral conversions as warnings") public static let disableLegacyTypeInfo: Option = Option("-disable-legacy-type-info", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Completely disable legacy type layout") @@ -81,13 +86,13 @@ extension Option { public static let disableNskeyedarchiverDiagnostics: Option = Option("-disable-nskeyedarchiver-diagnostics", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Allow classes with unstable mangled names to adopt NSCoding") public static let disableObjcAttrRequiresFoundationModule: Option = Option("-disable-objc-attr-requires-foundation-module", .flag, attributes: [.helpHidden, .frontend, .noDriver, .moduleInterface], helpText: "Disable requiring uses of @objc to require importing the Foundation module") public static let disableObjcInterop: Option = Option("-disable-objc-interop", .flag, attributes: [.helpHidden, .frontend, .noDriver, .moduleInterface], helpText: "Disable Objective-C interop code generation and config directives") + public static let disableOnlyOneDependencyFile: Option = Option("-disable-only-one-dependency-file", .flag, attributes: [.doesNotAffectIncrementalBuild], helpText: "Disables incremental build optimization that only produces one dependencies file") public static let disableOssaOpts: Option = Option("-disable-ossa-opts", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Don't run SIL OSSA optimization passes.") public static let disableParserLookup: Option = Option("-disable-parser-lookup", .flag, attributes: [.frontend], helpText: "Disable parser lookup & use ast scope lookup only (experimental)") public static let disablePlaygroundTransform: Option = Option("-disable-playground-transform", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable playground transformation") public static let disablePreviousImplementationCallsInDynamicReplacements: Option = Option("-disable-previous-implementation-calls-in-dynamic-replacements", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable calling the previous implementation in dynamic replacements") public static let disableReflectionMetadata: Option = Option("-disable-reflection-metadata", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable emission of reflection metadata for nominal types") public static let disableReflectionNames: Option = Option("-disable-reflection-names", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable emission of names of stored properties and enum cases inreflection metadata") - public static let disableSerializationNestedTypeLookupTable: Option = Option("-disable-serialization-nested-type-lookup-table", .flag, attributes: [.frontend, .noDriver], helpText: "Force module merging to use regular lookups to find nested types") public static let disableSilOwnershipVerifier: Option = Option("-disable-sil-ownership-verifier", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Do not verify ownership invariants during SIL Verification ") public static let disableSilPartialApply: Option = Option("-disable-sil-partial-apply", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable use of partial_apply in SIL generation") public static let disableSilPerfOptzns: Option = Option("-disable-sil-perf-optzns", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Don't run SIL performance optimization passes") @@ -96,6 +101,7 @@ extension Option { public static let disableSwift3ObjcInference: Option = Option("-disable-swift3-objc-inference", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable Swift 3's @objc inference rules for NSObject-derived classes and 'dynamic' members (emulates Swift 4 behavior)") public static let disableTargetOsChecking: Option = Option("-disable-target-os-checking", .flag, attributes: [.frontend, .noDriver], helpText: "Disable checking the target OS of serialized modules") public static let disableTestableAttrRequiresTestableModule: Option = Option("-disable-testable-attr-requires-testable-module", .flag, attributes: [.frontend, .noDriver], helpText: "Disable checking of @testable") + public static let disableTypeFingerprints: Option = Option("-disable-type-fingerprints", .flag, attributes: [.helpHidden, .frontend], helpText: "Disable per-nominal and extension body fingerprints") public static let disableTypoCorrection: Option = Option("-disable-typo-correction", .flag, attributes: [.frontend, .noDriver], helpText: "Disable typo correction") public static let disableVerifyExclusivity: Option = Option("-disable-verify-exclusivity", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Diable verification of access markers used to enforce exclusivity.") public static let driverAlwaysRebuildDependents: Option = Option("-driver-always-rebuild-dependents", .flag, attributes: [.helpHidden, .doesNotAffectIncrementalBuild], helpText: "Always rebuild dependents of files that have been modified", group: .internalDebug) @@ -138,6 +144,7 @@ extension Option { public static let D: Option = Option("-D", .joinedOrSeparate, attributes: [.frontend], helpText: "Marks a conditional compilation flag as true") public static let embedBitcodeMarker: Option = Option("-embed-bitcode-marker", .flag, attributes: [.frontend, .noInteractive], helpText: "Embed placeholder LLVM IR data as a marker") public static let embedBitcode: Option = Option("-embed-bitcode", .flag, attributes: [.frontend, .noInteractive], helpText: "Embed LLVM IR bitcode as data") + public static let embedTbdForModule: Option = Option("-embed-tbd-for-module", .separate, attributes: [.frontend], helpText: "Embed symbols from the module in the emitted tbd file") public static let emitAssembly: Option = Option("-emit-assembly", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild], helpText: "Emit assembly file(s) (-S)", group: .modes) public static let emitBc: Option = Option("-emit-bc", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild], helpText: "Emit LLVM BC file(s)", group: .modes) public static let emitCompiledSourcePath: Option = Option("-emit-compiled-source-path", .separate, attributes: [.frontend, .noDriver], metaVar: "", helpText: "Output compiled source to ") @@ -145,9 +152,11 @@ extension Option { public static let emitDependenciesPath: Option = Option("-emit-dependencies-path", .separate, attributes: [.frontend, .noDriver], metaVar: "", helpText: "Output basic Make-compatible dependencies file to ") public static let emitDependencies: Option = Option("-emit-dependencies", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild], helpText: "Emit basic Make-compatible dependencies files") public static let emitExecutable: Option = Option("-emit-executable", .flag, attributes: [.noInteractive, .doesNotAffectIncrementalBuild], helpText: "Emit a linked executable", group: .modes) + public static let emitFineGrainedDependencySourcefileDotFiles: Option = Option("-emit-fine-grained-dependency-sourcefile-dot-files", .flag, attributes: [.helpHidden, .doesNotAffectIncrementalBuild], helpText: "Emit dot files for every source file.", group: .internalDebug) public static let emitFixitsPath: Option = Option("-emit-fixits-path", .separate, attributes: [.frontend, .noDriver], metaVar: "", helpText: "Output compiler fixits as source edits to ") public static let emitImportedModules: Option = Option("-emit-imported-modules", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild], helpText: "Emit a list of the imported modules", group: .modes) public static let emitIr: Option = Option("-emit-ir", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild], helpText: "Emit LLVM IR file(s)", group: .modes) + public static let emitLdaddCfilePath: Option = Option("-emit-ldadd-cfile-path", .separate, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "", helpText: "Generate .c file defining symbols to add back") public static let emitLibrary: Option = Option("-emit-library", .flag, attributes: [.noInteractive], helpText: "Emit a linked library", group: .modes) public static let emitLoadedModuleTracePathEQ: Option = Option("-emit-loaded-module-trace-path=", .joined, alias: Option.emitLoadedModuleTracePath, attributes: [.frontend, .noInteractive, .argumentIsPath]) public static let emitLoadedModuleTracePath: Option = Option("-emit-loaded-module-trace-path", .separate, attributes: [.frontend, .noInteractive, .argumentIsPath], metaVar: "", helpText: "Emit the loaded module trace JSON to ") @@ -197,7 +206,7 @@ extension Option { public static let enableExperimentalConcisePoundFile: Option = Option("-enable-experimental-concise-pound-file", .flag, attributes: [.frontend], helpText: "Enable experimental concise '#file' identifier and '#filePath' alternative") public static let enableExperimentalDifferentiableProgramming: Option = Option("-enable-experimental-differentiable-programming", .flag, attributes: [.frontend], helpText: "Enable experimental differentiable programming features") public static let enableExperimentalStaticAssert: Option = Option("-enable-experimental-static-assert", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable experimental #assert") - public static let enableFineGrainedDependencies: Option = Option("-enable-fine-grained-dependencies", .flag, attributes: [.helpHidden, .frontend], helpText: "Experimental work-in-progress to be more selective about incremental recompilation") + public static let enableFineGrainedDependencies: Option = Option("-enable-fine-grained-dependencies", .flag, attributes: [.helpHidden, .frontend], helpText: "Be more selective about incremental recompilation") public static let enableImplicitDynamic: Option = Option("-enable-implicit-dynamic", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Add 'dynamic' to all declarations") public static let enableInferImportAsMember: Option = Option("-enable-infer-import-as-member", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Infer when a global could be imported as a member") public static let enableInvalidEphemeralnessAsError: Option = Option("-enable-invalid-ephemeralness-as-error", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Diagnose invalid ephemeral to non-ephemeral conversions as errors") @@ -208,6 +217,7 @@ extension Option { public static let enableNskeyedarchiverDiagnostics: Option = Option("-enable-nskeyedarchiver-diagnostics", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Diagnose classes with unstable mangled names adopting NSCoding") public static let enableObjcAttrRequiresFoundationModule: Option = Option("-enable-objc-attr-requires-foundation-module", .flag, attributes: [.helpHidden, .frontend, .noDriver, .moduleInterface], helpText: "Enable requiring uses of @objc to require importing the Foundation module") public static let enableObjcInterop: Option = Option("-enable-objc-interop", .flag, attributes: [.helpHidden, .frontend, .noDriver, .moduleInterface], helpText: "Enable Objective-C interop code generation and config directives") + public static let enableOnlyOneDependencyFile: Option = Option("-enable-only-one-dependency-file", .flag, attributes: [.doesNotAffectIncrementalBuild], helpText: "Enables incremental build optimization that only produces one dependencies file") public static let enableOperatorDesignatedTypes: Option = Option("-enable-operator-designated-types", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable operator designated types") public static let enableOwnershipStrippingAfterSerialization: Option = Option("-enable-ownership-stripping-after-serialization", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Strip ownership after serialization") public static let enablePrivateImports: Option = Option("-enable-private-imports", .flag, attributes: [.helpHidden, .frontend, .noInteractive], helpText: "Allows this module's internal and private API to be accessed") @@ -215,6 +225,7 @@ extension Option { public static let enableSilOpaqueValues: Option = Option("-enable-sil-opaque-values", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable SIL Opaque Values") public static let enableSourceImport: Option = Option("-enable-source-import", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable importing of Swift source files") public static let enableSourceRangeDependencies: Option = Option("-enable-source-range-dependencies", .flag, helpText: "Try using source range information") + public static let enableSpecDevirt: Option = Option("-enable-spec-devirt", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable speculative devirtualization pass.") public static let enableSubstSilFunctionTypesForFunctionValues: Option = Option("-enable-subst-sil-function-types-for-function-values", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Use substituted function types for SIL type lowering of function values") public static let enableSwift3ObjcInference: Option = Option("-enable-swift3-objc-inference", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable Swift 3's @objc inference rules for NSObject-derived classes and 'dynamic' members (emulates Swift 3 behavior)") public static let enableSwiftcall: Option = Option("-enable-swiftcall", .flag, attributes: [.frontend, .noDriver], helpText: "Enable the use of LLVM swiftcall support") @@ -222,18 +233,21 @@ extension Option { public static let enableTestableAttrRequiresTestableModule: Option = Option("-enable-testable-attr-requires-testable-module", .flag, attributes: [.frontend, .noDriver], helpText: "Enable checking of @testable") public static let enableTesting: Option = Option("-enable-testing", .flag, attributes: [.helpHidden, .frontend, .noInteractive], helpText: "Allows this module's internal API to be accessed for testing") public static let enableThrowWithoutTry: Option = Option("-enable-throw-without-try", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Allow throwing function calls without 'try'") + public static let enableTypeFingerprints: Option = Option("-enable-type-fingerprints", .flag, attributes: [.helpHidden, .frontend], helpText: "Enable per-nominal and extension body fingerprints") public static let enableVerifyExclusivity: Option = Option("-enable-verify-exclusivity", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable verification of access markers used to enforce exclusivity.") public static let enforceExclusivityEQ: Option = Option("-enforce-exclusivity=", .joined, attributes: [.frontend, .moduleInterface], metaVar: "", helpText: "Enforce law of exclusivity") + public static let experimentalPrintFullConvention: Option = Option("-experimental-print-full-convention", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "When emitting a module interface, emit additional @convention arguments, regardless of whether they were written in the source") public static let experimentalSkipNonInlinableFunctionBodies: Option = Option("-experimental-skip-non-inlinable-function-bodies", .flag, attributes: [.helpHidden, .frontend], helpText: "Skip type-checking and SIL generation for non-inlinable function bodies") public static let externalPassPipelineFilename: Option = Option("-external-pass-pipeline-filename", .separate, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "", helpText: "Use the pass pipeline defined by ") public static let FEQ: Option = Option("-F=", .joined, alias: Option.F, attributes: [.frontend, .argumentIsPath]) public static let filelist: Option = Option("-filelist", .separate, attributes: [.frontend, .noDriver], helpText: "Specify source inputs in a file rather than on the command line") - public static let fineGrainedDependencyIncludeIntrafile: Option = Option("-fine-grained-dependency-include-intrafile", .flag, attributes: [.helpHidden, .doesNotAffectIncrementalBuild], helpText: "Include within-file dependencies.", group: .internalDebug) + public static let fineGrainedDependencyIncludeIntrafile: Option = Option("-fine-grained-dependency-include-intrafile", .flag, attributes: [.helpHidden, .frontend], helpText: "Include within-file dependencies.") public static let fixitAll: Option = Option("-fixit-all", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild], helpText: "Apply all fixits from diagnostics without any filtering") public static let forcePublicLinkage: Option = Option("-force-public-linkage", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Force public linkage for private symbols. Used by LLDB.") public static let forceSingleFrontendInvocation: Option = Option("-force-single-frontend-invocation", .flag, alias: Option.wholeModuleOptimization, attributes: [.helpHidden, .frontend, .noInteractive]) public static let framework: Option = Option("-framework", .separate, attributes: [.frontend, .doesNotAffectIncrementalBuild], helpText: "Specifies a framework which should be linked against", group: .linkerOption) public static let Fsystem: Option = Option("-Fsystem", .separate, attributes: [.frontend, .argumentIsPath], helpText: "Add directory to system framework search path") + public static let functionSections: Option = Option("-function-sections", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Emit functions to separate sections.") public static let F: Option = Option("-F", .joinedOrSeparate, attributes: [.frontend, .argumentIsPath], helpText: "Add directory to framework search path") public static let gdwarfTypes: Option = Option("-gdwarf-types", .flag, attributes: [.frontend], helpText: "Emit full DWARF type info.", group: .g) public static let glineTablesOnly: Option = Option("-gline-tables-only", .flag, attributes: [.frontend], helpText: "Emit minimal debug info for backtraces only", group: .g) @@ -291,6 +305,7 @@ extension Option { public static let noStaticStdlib: Option = Option("-no-static-stdlib", .flag, attributes: [.helpHidden, .doesNotAffectIncrementalBuild], helpText: "Don't statically link the Swift standard library") public static let noStdlibRpath: Option = Option("-no-stdlib-rpath", .flag, attributes: [.helpHidden, .doesNotAffectIncrementalBuild], helpText: "Don't add any rpath entries.") public static let noToolchainStdlibRpath: Option = Option("-no-toolchain-stdlib-rpath", .flag, attributes: [.helpHidden, .doesNotAffectIncrementalBuild], helpText: "Do not add an rpath entry for the toolchain's standard library (default)") + public static let noWholeModuleOptimization: Option = Option("-no-whole-module-optimization", .flag, attributes: [.frontend, .noInteractive], helpText: "Disable optimizing input files together instead of individually") public static let nostdimport: Option = Option("-nostdimport", .flag, attributes: [.frontend], helpText: "Don't search the standard library import path for modules") public static let numThreads: Option = Option("-num-threads", .separate, attributes: [.frontend, .doesNotAffectIncrementalBuild], metaVar: "", helpText: "Enable multi-threading and specify number of threads") public static let Onone: Option = Option("-Onone", .flag, attributes: [.frontend, .moduleInterface], helpText: "Compile without any optimization", group: .O) @@ -300,7 +315,7 @@ extension Option { public static let outputFileMapEQ: Option = Option("-output-file-map=", .joined, alias: Option.outputFileMap, attributes: [.noInteractive, .argumentIsPath]) public static let outputFileMap: Option = Option("-output-file-map", .separate, attributes: [.noInteractive, .argumentIsPath], metaVar: "", helpText: "A file which specifies the location of outputs") public static let outputFilelist: Option = Option("-output-filelist", .separate, attributes: [.frontend, .noDriver], helpText: "Specify outputs in a file rather than on the command line") - public static let outputRequestGraphviz: Option = Option("-output-request-graphviz", .separate, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Emit GraphViz output visualizing the request graph") + public static let outputRequestGraphviz: Option = Option("-output-request-graphviz", .separate, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Emit GraphViz output visualizing the request dependency graph") public static let O: Option = Option("-O", .flag, attributes: [.frontend, .moduleInterface], helpText: "Compile with optimizations", group: .O) public static let o: Option = Option("-o", .joinedOrSeparate, attributes: [.frontend, .noInteractive, .autolinkExtract, .moduleWrap, .indent, .argumentIsPath], metaVar: "", helpText: "Write output to ") public static let packageDescriptionVersion: Option = Option("-package-description-version", .separate, attributes: [.helpHidden, .frontend, .moduleInterface], metaVar: "", helpText: "The version number to be applied on the input for the PackageDescription availability kind") @@ -316,6 +331,7 @@ extension Option { public static let playground: Option = Option("-playground", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Apply the playground semantics and transformation") public static let prebuiltModuleCachePathEQ: Option = Option("-prebuilt-module-cache-path=", .joined, alias: Option.prebuiltModuleCachePath, attributes: [.helpHidden, .frontend, .noDriver]) public static let prebuiltModuleCachePath: Option = Option("-prebuilt-module-cache-path", .separate, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Directory of prebuilt modules for loading module interfaces") + public static let previousModuleInstallnameMapFile: Option = Option("-previous-module-installname-map-file", .separate, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "", helpText: "Path to a Json file indicating module name to installname map for @_originallyDefinedIn") public static let primaryFilelist: Option = Option("-primary-filelist", .separate, attributes: [.frontend, .noDriver], helpText: "Specify primary inputs in a file rather than on the command line") public static let primaryFile: Option = Option("-primary-file", .separate, attributes: [.frontend, .noDriver], helpText: "Produce output for this file, not the whole module") public static let printAst: Option = Option("-print-ast", .flag, attributes: [.frontend, .noInteractive, .doesNotAffectIncrementalBuild], helpText: "Parse and type-check input file(s) and pretty print AST(s)", group: .modes) @@ -380,6 +396,7 @@ extension Option { public static let S: Option = Option("-S", .flag, alias: Option.emitAssembly, attributes: [.frontend, .noInteractive], group: .modes) public static let tabWidth: Option = Option("-tab-width", .separate, attributes: [.noInteractive, .noBatch, .indent], metaVar: "", helpText: "Width of tab character.", group: .codeFormatting) public static let targetCpu: Option = Option("-target-cpu", .separate, attributes: [.frontend, .moduleInterface], helpText: "Generate code for a particular CPU variant") + public static let targetVariant: Option = Option("-target-variant", .separate, attributes: [.frontend], helpText: "Generate 'zippered' code for macCatalyst that can run on the specified variant target triple in addition to the main -target triple") public static let targetLegacySpelling: Option = Option("--target=", .joined, alias: Option.target, attributes: [.frontend]) public static let target: Option = Option("-target", .separate, attributes: [.frontend, .moduleWrap, .moduleInterface], metaVar: "", helpText: "Generate code for the given target , such as x86_64-apple-macos10.9") public static let tbdCompatibilityVersionEQ: Option = Option("-tbd-compatibility-version=", .joined, alias: Option.tbdCompatibilityVersion, attributes: [.frontend, .noDriver]) @@ -428,7 +445,6 @@ extension Option { public static let warnSwift3ObjcInference: Option = Option("-warn-swift3-objc-inference", .flag, alias: Option.warnSwift3ObjcInferenceComplete, attributes: [.helpHidden, .frontend, .doesNotAffectIncrementalBuild]) public static let warningsAsErrors: Option = Option("-warnings-as-errors", .flag, attributes: [.frontend], helpText: "Treat warnings as errors") public static let wholeModuleOptimization: Option = Option("-whole-module-optimization", .flag, attributes: [.frontend, .noInteractive], helpText: "Optimize input files together instead of individually") - public static let noWholeModuleOptimization: Option = Option("-no-whole-module-optimization", .flag, attributes: [.frontend, .noInteractive], helpText: "Disable optimizing input files together instead of individually") public static let wmo: Option = Option("-wmo", .flag, alias: Option.wholeModuleOptimization, attributes: [.helpHidden, .frontend, .noInteractive]) public static let workingDirectoryEQ: Option = Option("-working-directory=", .joined, alias: Option.workingDirectory) public static let workingDirectory: Option = Option("-working-directory", .separate, metaVar: "", helpText: "Resolve file paths relative to the specified directory") @@ -452,7 +468,9 @@ extension Option { Option.AssumeSingleThreaded, Option.autolinkForceLoad, Option.autolinkLibrary, + Option.avoidEmitModuleSourceInfo, Option.buildModuleFromParseableInterface, + Option.buildRequestDependencyGraph, Option.bypassBatchModeChecks, Option.checkOnoneCompleteness, Option.codeCompleteCallPatternHeuristics, @@ -495,10 +513,13 @@ extension Option { Option.disableAvailabilityChecking, Option.disableBatchMode, Option.disableBridgingPch, + Option.disableClangimporterSourceImport, Option.disableConstraintSolverPerformanceHacks, Option.disableDebuggerShadowCopies, Option.disableDeserializationRecovery, Option.disableDiagnosticPasses, + Option.disableFineGrainedDependencies, + Option.disableGenericMetadataPrespecialization, Option.disableIncrementalLlvmCodegeneration, Option.disableInvalidEphemeralnessAsError, Option.disableLegacyTypeInfo, @@ -513,13 +534,13 @@ extension Option { Option.disableNskeyedarchiverDiagnostics, Option.disableObjcAttrRequiresFoundationModule, Option.disableObjcInterop, + Option.disableOnlyOneDependencyFile, Option.disableOssaOpts, Option.disableParserLookup, Option.disablePlaygroundTransform, Option.disablePreviousImplementationCallsInDynamicReplacements, Option.disableReflectionMetadata, Option.disableReflectionNames, - Option.disableSerializationNestedTypeLookupTable, Option.disableSilOwnershipVerifier, Option.disableSilPartialApply, Option.disableSilPerfOptzns, @@ -528,6 +549,7 @@ extension Option { Option.disableSwift3ObjcInference, Option.disableTargetOsChecking, Option.disableTestableAttrRequiresTestableModule, + Option.disableTypeFingerprints, Option.disableTypoCorrection, Option.disableVerifyExclusivity, Option.driverAlwaysRebuildDependents, @@ -570,6 +592,7 @@ extension Option { Option.D, Option.embedBitcodeMarker, Option.embedBitcode, + Option.embedTbdForModule, Option.emitAssembly, Option.emitBc, Option.emitCompiledSourcePath, @@ -577,9 +600,11 @@ extension Option { Option.emitDependenciesPath, Option.emitDependencies, Option.emitExecutable, + Option.emitFineGrainedDependencySourcefileDotFiles, Option.emitFixitsPath, Option.emitImportedModules, Option.emitIr, + Option.emitLdaddCfilePath, Option.emitLibrary, Option.emitLoadedModuleTracePathEQ, Option.emitLoadedModuleTracePath, @@ -640,6 +665,7 @@ extension Option { Option.enableNskeyedarchiverDiagnostics, Option.enableObjcAttrRequiresFoundationModule, Option.enableObjcInterop, + Option.enableOnlyOneDependencyFile, Option.enableOperatorDesignatedTypes, Option.enableOwnershipStrippingAfterSerialization, Option.enablePrivateImports, @@ -647,6 +673,7 @@ extension Option { Option.enableSilOpaqueValues, Option.enableSourceImport, Option.enableSourceRangeDependencies, + Option.enableSpecDevirt, Option.enableSubstSilFunctionTypesForFunctionValues, Option.enableSwift3ObjcInference, Option.enableSwiftcall, @@ -654,8 +681,10 @@ extension Option { Option.enableTestableAttrRequiresTestableModule, Option.enableTesting, Option.enableThrowWithoutTry, + Option.enableTypeFingerprints, Option.enableVerifyExclusivity, Option.enforceExclusivityEQ, + Option.experimentalPrintFullConvention, Option.experimentalSkipNonInlinableFunctionBodies, Option.externalPassPipelineFilename, Option.FEQ, @@ -666,6 +695,7 @@ extension Option { Option.forceSingleFrontendInvocation, Option.framework, Option.Fsystem, + Option.functionSections, Option.F, Option.gdwarfTypes, Option.glineTablesOnly, @@ -723,8 +753,8 @@ extension Option { Option.noStaticStdlib, Option.noStdlibRpath, Option.noToolchainStdlibRpath, - Option.nostdimport, Option.noWholeModuleOptimization, + Option.nostdimport, Option.numThreads, Option.Onone, Option.Oplayground, @@ -749,6 +779,7 @@ extension Option { Option.playground, Option.prebuiltModuleCachePathEQ, Option.prebuiltModuleCachePath, + Option.previousModuleInstallnameMapFile, Option.primaryFilelist, Option.primaryFile, Option.printAst, @@ -813,6 +844,7 @@ extension Option { Option.S, Option.tabWidth, Option.targetCpu, + Option.targetVariant, Option.targetLegacySpelling, Option.target, Option.tbdCompatibilityVersionEQ, diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index 466073180..d5b302910 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -682,6 +682,29 @@ final class SwiftDriverTests: XCTestCase { XCTAssertFalse(cmd.contains(.flag("-shared"))) } + do { + // macOS catalyst target + var driver = try Driver(args: commonArgs + ["-emit-library", "-target", "x86_64-apple-ios13.0-macabi"], env: env) + let plannedJobs = try driver.planBuild() + + XCTAssertEqual(3, plannedJobs.count) + XCTAssertFalse(plannedJobs.contains { $0.kind == .autolinkExtract }) + + let linkJob = plannedJobs[2] + XCTAssertEqual(linkJob.kind, .link) + + let cmd = linkJob.commandLine + XCTAssertTrue(cmd.contains(.flag("-dylib"))) + XCTAssertTrue(cmd.contains(.flag("-arch"))) + XCTAssertTrue(cmd.contains(.flag("x86_64"))) + XCTAssertTrue(cmd.contains(.flag("-maccatalyst_version_min"))) + XCTAssertTrue(cmd.contains(.flag("13.0.0"))) + XCTAssertEqual(linkJob.outputs[0].file, try VirtualPath(path: "libTest.dylib")) + + XCTAssertFalse(cmd.contains(.flag("-static"))) + XCTAssertFalse(cmd.contains(.flag("-shared"))) + } + do { // Xlinker flags var driver = try Driver(args: commonArgs + ["-emit-library", "-L", "/tmp", "-Xlinker", "-w", "-target", "x86_64-apple-macosx10.15"], env: env) @@ -1193,6 +1216,64 @@ final class SwiftDriverTests: XCTestCase { XCTAssertEqual(driver3.targetTriple.triple, "x86_64-unknown-watchos12") } + func testTargetVariant() throws { + do { + var driver = try Driver(args: ["swiftc", "-c", "-target", "x86_64-apple-ios13.0-macabi", "-target-variant", "x86_64-apple-macosx10.14", "foo.swift"]) + let plannedJobs = try driver.planBuild() + XCTAssertEqual(plannedJobs.count, 1) + + XCTAssertEqual(plannedJobs[0].kind, .compile) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("-target"))) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("x86_64-apple-ios13.0-macabi"))) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("-target-variant"))) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("x86_64-apple-macosx10.14"))) + } + + do { + var driver = try Driver(args: ["swiftc", "-emit-library", "-target", "x86_64-apple-ios13.0-macabi", "-target-variant", "x86_64-apple-macosx10.14", "-module-name", "foo", "foo.swift"]) + let plannedJobs = try driver.planBuild() + XCTAssertEqual(plannedJobs.count, 2) + + XCTAssertEqual(plannedJobs[0].kind, .compile) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("-target"))) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("x86_64-apple-ios13.0-macabi"))) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("-target-variant"))) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("x86_64-apple-macosx10.14"))) + + XCTAssertEqual(plannedJobs[1].kind, .link) + XCTAssert(plannedJobs[1].commandLine.contains(.flag("-maccatalyst_version_min"))) + XCTAssert(plannedJobs[1].commandLine.contains(.flag("13.0.0"))) + XCTAssert(plannedJobs[1].commandLine.contains(.flag("-macosx_version_min"))) + XCTAssert(plannedJobs[1].commandLine.contains(.flag("10.14.0"))) + } + + // Test -target-variant is passed to generate pch job + do { + var driver = try Driver(args: ["swiftc", "-target", "x86_64-apple-ios13.0-macabi", "-target-variant", "x86_64-apple-macosx10.14", "-enable-bridging-pch", "-import-objc-header", "TestInputHeader.h", "foo.swift"]) + let plannedJobs = try driver.planBuild() + XCTAssertEqual(plannedJobs.count, 3) + + XCTAssertEqual(plannedJobs[0].kind, .generatePCH) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("-emit-pch"))) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("-target"))) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("x86_64-apple-ios13.0-macabi"))) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("-target-variant"))) + XCTAssert(plannedJobs[0].commandLine.contains(.flag("x86_64-apple-macosx10.14"))) + + XCTAssertEqual(plannedJobs[1].kind, .compile) + XCTAssert(plannedJobs[1].commandLine.contains(.flag("-target"))) + XCTAssert(plannedJobs[1].commandLine.contains(.flag("x86_64-apple-ios13.0-macabi"))) + XCTAssert(plannedJobs[1].commandLine.contains(.flag("-target-variant"))) + XCTAssert(plannedJobs[1].commandLine.contains(.flag("x86_64-apple-macosx10.14"))) + + XCTAssertEqual(plannedJobs[2].kind, .link) + XCTAssert(plannedJobs[2].commandLine.contains(.flag("-maccatalyst_version_min"))) + XCTAssert(plannedJobs[2].commandLine.contains(.flag("13.0.0"))) + XCTAssert(plannedJobs[2].commandLine.contains(.flag("-macosx_version_min"))) + XCTAssert(plannedJobs[2].commandLine.contains(.flag("10.14.0"))) + } + } + func testDSYMGeneration() throws { let commonArgs = [ "swiftc", "foo.swift", "bar.swift", @@ -1369,15 +1450,30 @@ final class SwiftDriverTests: XCTestCase { } func testPrintTargetInfo() throws { - var driver = try Driver(args: ["swift", "-print-target-info", "-target", "arm64-apple-ios12.0", "-sdk", "bar", "-resource-dir", "baz"]) - let plannedJobs = try driver.planBuild() - XCTAssertTrue(plannedJobs.count == 1) - let job = plannedJobs[0] - XCTAssertEqual(job.kind, .printTargetInfo) - XCTAssertTrue(job.commandLine.contains(.flag("-print-target-info"))) - XCTAssertTrue(job.commandLine.contains(.flag("-target"))) - XCTAssertTrue(job.commandLine.contains(.flag("-sdk"))) - XCTAssertTrue(job.commandLine.contains(.flag("-resource-dir"))) + do { + var driver = try Driver(args: ["swift", "-print-target-info", "-target", "arm64-apple-ios12.0", "-sdk", "bar", "-resource-dir", "baz"]) + let plannedJobs = try driver.planBuild() + XCTAssertTrue(plannedJobs.count == 1) + let job = plannedJobs[0] + XCTAssertEqual(job.kind, .printTargetInfo) + XCTAssertTrue(job.commandLine.contains(.flag("-print-target-info"))) + XCTAssertTrue(job.commandLine.contains(.flag("-target"))) + XCTAssertTrue(job.commandLine.contains(.flag("-sdk"))) + XCTAssertTrue(job.commandLine.contains(.flag("-resource-dir"))) + } + + do { + var driver = try Driver(args: ["swift", "-print-target-info", "-target", "x86_64-apple-ios13.0-macabi", "-target-variant", "x86_64-apple-macosx10.14", "-sdk", "bar", "-resource-dir", "baz"]) + let plannedJobs = try driver.planBuild() + XCTAssertTrue(plannedJobs.count == 1) + let job = plannedJobs[0] + XCTAssertEqual(job.kind, .printTargetInfo) + XCTAssertTrue(job.commandLine.contains(.flag("-print-target-info"))) + XCTAssertTrue(job.commandLine.contains(.flag("-target"))) + XCTAssertTrue(job.commandLine.contains(.flag("-target-variant"))) + XCTAssertTrue(job.commandLine.contains(.flag("-sdk"))) + XCTAssertTrue(job.commandLine.contains(.flag("-resource-dir"))) + } } func testPCHGeneration() throws { diff --git a/Tests/SwiftDriverTests/TripleTests.swift b/Tests/SwiftDriverTests/TripleTests.swift index 04212f05b..8b25d10a5 100644 --- a/Tests/SwiftDriverTests/TripleTests.swift +++ b/Tests/SwiftDriverTests/TripleTests.swift @@ -995,10 +995,10 @@ final class TripleTests: XCTestCase { nonDarwin: true ) - func assertDarwinPlatformCorrect( + func assertDarwinPlatformCorrect( _ triple: Triple, - case match: (DarwinPlatform) -> DarwinPlatform.Environment?, - environment: DarwinPlatform.Environment, + case match: (DarwinPlatform) -> T?, + environment: T, macOSVersion: Triple.Version?, iOSVersion: Triple.Version?, watchOSVersion: Triple.Version?, @@ -1055,10 +1055,10 @@ final class TripleTests: XCTestCase { func iOS(_ platform: DarwinPlatform) -> DarwinPlatform.Environment? { if case .iOS(let env) = platform { return env } else { return nil } } - func tvOS(_ platform: DarwinPlatform) -> DarwinPlatform.Environment? { + func tvOS(_ platform: DarwinPlatform) -> DarwinPlatform.EnvironmentWithoutCatalyst? { if case .tvOS(let env) = platform { return env } else { return nil } } - func watchOS(_ platform: DarwinPlatform) -> DarwinPlatform.Environment? { + func watchOS(_ platform: DarwinPlatform) -> DarwinPlatform.EnvironmentWithoutCatalyst? { if case .watchOS(let env) = platform { return env } else { return nil } } @@ -1116,7 +1116,7 @@ final class TripleTests: XCTestCase { shouldHaveJetPacks: true) assertDarwinPlatformCorrect(iOS3, case: iOS, - environment: .simulator, // FIXME: macCatalyst + environment: .catalyst, macOSVersion: .init(10, 4, 0), iOSVersion: .init(60, 0, 0), watchOSVersion: nil,