diff --git a/Sources/SwiftDriver/Jobs/CompileJob.swift b/Sources/SwiftDriver/Jobs/CompileJob.swift index dd9a7e378..c2b14156a 100644 --- a/Sources/SwiftDriver/Jobs/CompileJob.swift +++ b/Sources/SwiftDriver/Jobs/CompileJob.swift @@ -363,13 +363,18 @@ extension Driver { commandLine.appendFlag(map) } + let expirementalFeatures = parsedOptions.arguments(for: .enableExperimentalFeature) + let embeddedEnabled = expirementalFeatures.map(\.argument).map(\.asSingle).contains("Embedded") + try commandLine.appendLast(.trackSystemDependencies, from: &parsedOptions) try commandLine.appendLast(.CrossModuleOptimization, from: &parsedOptions) try commandLine.appendLast(.ExperimentalPerformanceAnnotations, from: &parsedOptions) - try commandLine.appendLast(.disableAutolinkingRuntimeCompatibility, from: &parsedOptions) + try commandLine.appendLast(.runtimeCompatibilityVersion, from: &parsedOptions) + try commandLine.appendLast(.disableAutolinkingRuntimeCompatibility, from: &parsedOptions) try commandLine.appendLast(.disableAutolinkingRuntimeCompatibilityDynamicReplacements, from: &parsedOptions) try commandLine.appendLast(.disableAutolinkingRuntimeCompatibilityConcurrency, from: &parsedOptions) + try commandLine.appendLast(.checkApiAvailabilityOnly, from: &parsedOptions) try addCommonSymbolGraphOptions(commandLine: &commandLine, diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index 519029afa..a45d4cea5 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -107,8 +107,11 @@ extension Driver { commandLine.appendFlag("-aarch64-use-tbi") } + let expirementalFeatures = parsedOptions.arguments(for: .enableExperimentalFeature) + let embeddedEnabled = expirementalFeatures.map(\.argument).map(\.asSingle).contains("Embedded") + // Enable or disable ObjC interop appropriately for the platform - if targetTriple.isDarwin { + if targetTriple.isDarwin && !embeddedEnabled { commandLine.appendFlag(.enableObjcInterop) } else { commandLine.appendFlag(.disableObjcInterop) @@ -122,6 +125,22 @@ extension Driver { commandLine.appendFlag("-stdlib=\(stdlibVariant)") } + if embeddedEnabled && parsedOptions.hasArgument(.enableLibraryEvolution) { + diagnosticEngine.emit(.error_no_library_evolution_embedded) + throw ErrorDiagnostics.emitted + } + + if embeddedEnabled && + (!parsedOptions.hasArgument(.wmo) || !parsedOptions.hasArgument(.wholeModuleOptimization)) { + diagnosticEngine.emit(.error_need_wmo_embedded) + throw ErrorDiagnostics.emitted + } + + if embeddedEnabled && parsedOptions.hasArgument(.enableObjcInterop) { + diagnosticEngine.emit(.error_no_objc_interop_embedded) + throw ErrorDiagnostics.emitted + } + // Handle the CPU and its preferences. try commandLine.appendLast(.targetCpu, from: &parsedOptions) diff --git a/Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift b/Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift index 5b73fc1db..374fdd51a 100644 --- a/Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift +++ b/Sources/SwiftDriver/Jobs/Toolchain+LinkerSupport.swift @@ -117,21 +117,26 @@ extension DarwinToolchain { } } - for compatibilityLib in targetInfo.target.compatibilityLibraries { - let shouldLink: Bool - switch compatibilityLib.filter { - case .all: - shouldLink = true - break - - case .executable: - shouldLink = linkerOutputType == .executable - } + let expirementalFeatures = parsedOptions.arguments(for: .enableExperimentalFeature) + let embeddedEnabled = expirementalFeatures.map(\.argument).map(\.asSingle).contains("Embedded") + + if !embeddedEnabled { + for compatibilityLib in targetInfo.target.compatibilityLibraries { + let shouldLink: Bool + switch compatibilityLib.filter { + case .all: + shouldLink = true + break + + case .executable: + shouldLink = linkerOutputType == .executable + } - if shouldLink { - // Old frontends don't set forceLoad at all; assume it's true in that case - try addArgsForBackDeployLib("lib" + compatibilityLib.libraryName + ".a", - forceLoad: compatibilityLib.forceLoad ?? true) + if shouldLink { + // Old frontends don't set forceLoad at all; assume it's true in that case + try addArgsForBackDeployLib("lib" + compatibilityLib.libraryName + ".a", + forceLoad: compatibilityLib.forceLoad ?? true) + } } } diff --git a/Sources/SwiftDriver/Utilities/Diagnostics.swift b/Sources/SwiftDriver/Utilities/Diagnostics.swift index a7ceb422d..0d1593e44 100644 --- a/Sources/SwiftDriver/Utilities/Diagnostics.swift +++ b/Sources/SwiftDriver/Utilities/Diagnostics.swift @@ -166,4 +166,16 @@ extension Diagnostic.Message { static func error_expected_frontend_command() -> Diagnostic.Message { .error("expected a swift frontend command") } + + static var error_no_library_evolution_embedded: Diagnostic.Message { + .error("Library evolution cannot be enabled with embedded Swift.") + } + + static var error_need_wmo_embedded: Diagnostic.Message { + .error("Whole module optimization (wmo) must be enabled with embedded Swift.") + } + + static var error_no_objc_interop_embedded: Diagnostic.Message { + .error("Objective-C interop cannot be enabled with embedded Swift.") + } } diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index fdd9937f1..218fe351f 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -9,7 +9,7 @@ // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// -@_spi(Testing) import SwiftDriver +@testable @_spi(Testing) import SwiftDriver import SwiftDriverExecution import SwiftOptions import TSCBasic @@ -6288,6 +6288,36 @@ final class SwiftDriverTests: XCTestCase { } } + func testEmbeddedSwiftOptions() throws { + do { + var driver = try Driver(args: ["swiftc", "-target", "arm64-apple-macosx10.13", "test.swift", "-enable-experimental-feature", "Embedded", "-parse-as-library", "-wmo", "-o", "a.out", "-module-name", "main"]) + let plannedJobs = try driver.planBuild() + XCTAssertEqual(plannedJobs.count, 2) + let compileJob = plannedJobs[0] + let linkJob = plannedJobs[1] + XCTAssertTrue(compileJob.commandLine.contains(.flag("-disable-objc-interop"))) + XCTAssertFalse(linkJob.commandLine.contains(.flag("-force_load"))) + } + do { + let diags = DiagnosticsEngine() + var driver = try Driver(args: ["swiftc", "-target", "arm64-apple-macosx10.13", "test.swift", "-enable-experimental-feature", "Embedded", "-parse-as-library", "-wmo", "-o", "a.out", "-module-name", "main", "-enable-library-evolution"], diagnosticsEngine: diags) + _ = try driver.planBuild() + XCTAssertTrue(diags.diagnostics.first!.message.text == Diagnostic.Message.error_no_library_evolution_embedded.text) + } catch _ { } + do { + let diags = DiagnosticsEngine() + var driver = try Driver(args: ["swiftc", "-target", "arm64-apple-macosx10.13", "test.swift", "-enable-experimental-feature", "Embedded", "-parse-as-library", "-o", "a.out", "-module-name", "main"], diagnosticsEngine: diags) + _ = try driver.planBuild() + XCTAssertTrue(diags.diagnostics.first!.message.text == Diagnostic.Message.error_need_wmo_embedded.text) + } catch _ { } + do { + let diags = DiagnosticsEngine() + var driver = try Driver(args: ["swiftc", "-target", "arm64-apple-macosx10.13", "test.swift", "-enable-experimental-feature", "Embedded", "-parse-as-library", "-wmo", "-o", "a.out", "-module-name", "main", "-enable-objc-interop"], diagnosticsEngine: diags) + _ = try driver.planBuild() + XCTAssertTrue(diags.diagnostics.first!.message.text == Diagnostic.Message.error_no_objc_interop_embedded.text) + } catch _ { } + } + func testVFSOverlay() throws { do { var driver = try Driver(args: ["swiftc", "-c", "-vfsoverlay", "overlay.yaml", "foo.swift"])