From 6e8ef822737cac0de6515ac3dea838b0fb4b8444 Mon Sep 17 00:00:00 2001 From: zoecarver Date: Tue, 26 Sep 2023 10:27:14 -0700 Subject: [PATCH 1/4] [embeded] A number of changes to support embeded Swift. --- Sources/SwiftDriver/Jobs/CompileJob.swift | 19 ++++++++--- .../SwiftDriver/Jobs/FrontendJobHelpers.swift | 21 +++++++++++- .../Jobs/Toolchain+LinkerSupport.swift | 33 +++++++++++-------- .../SwiftDriver/Utilities/Diagnostics.swift | 12 +++++++ Tests/SwiftDriverTests/SwiftDriverTests.swift | 30 +++++++++++++++++ 5 files changed, 96 insertions(+), 19 deletions(-) diff --git a/Sources/SwiftDriver/Jobs/CompileJob.swift b/Sources/SwiftDriver/Jobs/CompileJob.swift index dd9a7e378..ba990f54f 100644 --- a/Sources/SwiftDriver/Jobs/CompileJob.swift +++ b/Sources/SwiftDriver/Jobs/CompileJob.swift @@ -363,13 +363,24 @@ 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(.disableAutolinkingRuntimeCompatibilityDynamicReplacements, from: &parsedOptions) - try commandLine.appendLast(.disableAutolinkingRuntimeCompatibilityConcurrency, from: &parsedOptions) + + if !embeddedEnabled { + try commandLine.appendLast(.disableAutolinkingRuntimeCompatibility, from: &parsedOptions) + try commandLine.appendLast(.runtimeCompatibilityVersion, from: &parsedOptions) + try commandLine.appendLast(.disableAutolinkingRuntimeCompatibilityDynamicReplacements, from: &parsedOptions) + try commandLine.appendLast(.disableAutolinkingRuntimeCompatibilityConcurrency, from: &parsedOptions) + } else { + try commandLine.appendFlag(.disableAutolinkingRuntimeCompatibility) + try commandLine.appendFlag(.disableAutolinkingRuntimeCompatibilityDynamicReplacements) + try commandLine.appendFlag(.disableAutolinkingRuntimeCompatibilityConcurrency) + } + 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..f5a12526f 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -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 == "Library evolution cannot be enabled with embedded Swift.") + } 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 == "Whole module optimization (wmo) must be enabled with embedded Swift.") + } 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 == "Objective-C interop cannot be enabled with embedded Swift.") + } catch _ { } + } + func testVFSOverlay() throws { do { var driver = try Driver(args: ["swiftc", "-c", "-vfsoverlay", "overlay.yaml", "foo.swift"]) From ba66fdc4d88b8333de2bb98364894cd171016cea Mon Sep 17 00:00:00 2001 From: zoecarver Date: Mon, 2 Oct 2023 10:16:46 -0700 Subject: [PATCH 2/4] [embedded] fix test and address review comments --- Sources/SwiftDriver/Jobs/CompileJob.swift | 14 ++++---------- Tests/SwiftDriverTests/SwiftDriverTests.swift | 6 +++--- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/Sources/SwiftDriver/Jobs/CompileJob.swift b/Sources/SwiftDriver/Jobs/CompileJob.swift index ba990f54f..c2b14156a 100644 --- a/Sources/SwiftDriver/Jobs/CompileJob.swift +++ b/Sources/SwiftDriver/Jobs/CompileJob.swift @@ -370,16 +370,10 @@ extension Driver { try commandLine.appendLast(.CrossModuleOptimization, from: &parsedOptions) try commandLine.appendLast(.ExperimentalPerformanceAnnotations, from: &parsedOptions) - if !embeddedEnabled { - try commandLine.appendLast(.disableAutolinkingRuntimeCompatibility, from: &parsedOptions) - try commandLine.appendLast(.runtimeCompatibilityVersion, from: &parsedOptions) - try commandLine.appendLast(.disableAutolinkingRuntimeCompatibilityDynamicReplacements, from: &parsedOptions) - try commandLine.appendLast(.disableAutolinkingRuntimeCompatibilityConcurrency, from: &parsedOptions) - } else { - try commandLine.appendFlag(.disableAutolinkingRuntimeCompatibility) - try commandLine.appendFlag(.disableAutolinkingRuntimeCompatibilityDynamicReplacements) - try commandLine.appendFlag(.disableAutolinkingRuntimeCompatibilityConcurrency) - } + 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) diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index f5a12526f..5949bc8bb 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -6302,19 +6302,19 @@ final class SwiftDriverTests: XCTestCase { 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 == "Library evolution cannot be enabled with embedded Swift.") + XCTAssertTrue(diags.diagnostics.first!.message.text == error_no_library_evolution_embedded.message.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 == "Whole module optimization (wmo) must be enabled with embedded Swift.") + XCTAssertTrue(diags.diagnostics.first!.message.text == error_need_wmo_embedded.message.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 == "Objective-C interop cannot be enabled with embedded Swift.") + XCTAssertTrue(diags.diagnostics.first!.message.text == error_no_objc_interop_embedded.message.text) } catch _ { } } From 9279287632ed778f7a16e201aeeb9197dd217711 Mon Sep 17 00:00:00 2001 From: zoecarver Date: Mon, 2 Oct 2023 12:09:07 -0700 Subject: [PATCH 3/4] [embedded] revert test changes (just compare strings). --- Tests/SwiftDriverTests/SwiftDriverTests.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index 5949bc8bb..f5a12526f 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -6302,19 +6302,19 @@ final class SwiftDriverTests: XCTestCase { 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 == error_no_library_evolution_embedded.message.text) + XCTAssertTrue(diags.diagnostics.first!.message.text == "Library evolution cannot be enabled with embedded Swift.") } 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 == error_need_wmo_embedded.message.text) + XCTAssertTrue(diags.diagnostics.first!.message.text == "Whole module optimization (wmo) must be enabled with embedded Swift.") } 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 == error_no_objc_interop_embedded.message.text) + XCTAssertTrue(diags.diagnostics.first!.message.text == "Objective-C interop cannot be enabled with embedded Swift.") } catch _ { } } From c2a8868b014ed27bc3ca4a86197b34f54ddb7dae Mon Sep 17 00:00:00 2001 From: zoecarver Date: Mon, 2 Oct 2023 12:22:55 -0700 Subject: [PATCH 4/4] [embedded] Check that the messages match options exactly; use `@testable`. --- Tests/SwiftDriverTests/SwiftDriverTests.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index f5a12526f..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 @@ -6302,19 +6302,19 @@ final class SwiftDriverTests: XCTestCase { 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 == "Library evolution cannot be enabled with embedded Swift.") + 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 == "Whole module optimization (wmo) must be enabled with embedded Swift.") + 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 == "Objective-C interop cannot be enabled with embedded Swift.") + XCTAssertTrue(diags.diagnostics.first!.message.text == Diagnostic.Message.error_no_objc_interop_embedded.text) } catch _ { } }