diff --git a/Sources/Build/BuildDescription/SwiftModuleBuildDescription.swift b/Sources/Build/BuildDescription/SwiftModuleBuildDescription.swift index 721153fb251..69e482aec34 100644 --- a/Sources/Build/BuildDescription/SwiftModuleBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftModuleBuildDescription.swift @@ -490,9 +490,19 @@ public final class SwiftModuleBuildDescription { args += ["-v"] } - // Enable batch mode whenever WMO is off. - if !self.useWholeModuleOptimization { - args += ["-enable-batch-mode"] + if self.useWholeModuleOptimization { + args.append("-whole-module-optimization") + args.append("-num-threads") + args.append(String(ProcessInfo.processInfo.activeProcessorCount)) + } else { + args.append("-incremental") + args.append("-enable-batch-mode") + } + + // Workaround for https://github.com/swiftlang/swift-package-manager/issues/8648 + if self.useMergeableSymbols { + args.append("-Xfrontend") + args.append("-mergeable-symbols") } args += ["-serialize-diagnostics"] @@ -779,14 +789,6 @@ public final class SwiftModuleBuildDescription { result.append(outputFileMapPath.pathString) } - if self.useWholeModuleOptimization { - result.append("-whole-module-optimization") - result.append("-num-threads") - result.append(String(ProcessInfo.processInfo.activeProcessorCount)) - } else { - result.append("-incremental") - } - result.append("-c") result.append(contentsOf: self.sources.map(\.pathString)) @@ -1044,6 +1046,12 @@ public final class SwiftModuleBuildDescription { return true } } + + // Workaround for https://github.com/swiftlang/swift-package-manager/issues/8648 + /// Whether to build Swift code with -Xfrontend -mergeable-symbols. + package var useMergeableSymbols: Bool { + return self.target.underlying.isEmbeddedSwiftTarget + } } extension SwiftModuleBuildDescription { diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index be957b476b5..c2b40685efa 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -2240,17 +2240,61 @@ class BuildPlanTestCase: BuildSystemProviderTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) - // WMO should always be on with Embedded - let plan = try await mockBuildPlan( + // -Xfrontend -mergeable symbols should be passed with Embedded + let result = try await BuildPlanResult(plan: mockBuildPlan( graph: graph, fileSystem: fs, observabilityScope: observability.topScope + )) + result.checkTargetsCount(1) + + // Compile Swift Target + let aCompileArguments = try result.moduleBuildDescription(for: "A").swift().compileArguments() + let aCompileArgumentsPattern: [StringPattern] = ["-whole-module-optimization"] + let aCompileArgumentsNegativePattern: [StringPattern] = ["-wmo"] + XCTAssertMatch(aCompileArguments, aCompileArgumentsPattern) + XCTAssertNoMatch(aCompileArguments, aCompileArgumentsNegativePattern) + } + + // Workaround for: https://github.com/swiftlang/swift-package-manager/issues/8648 + func test_mergeableSymbols_enabledInEmbedded() async throws { + let Pkg: AbsolutePath = "/Pkg" + let fs: FileSystem = InMemoryFileSystem( + emptyFiles: + Pkg.appending(components: "Sources", "A", "A.swift").pathString ) - let a = try BuildPlanResult(plan: plan) - .moduleBuildDescription(for: "A").swift().emitCommandLine() - XCTAssertMatch(a, ["-whole-module-optimization"]) - XCTAssertNoMatch(a, ["-wmo"]) + let observability = ObservabilitySystem.makeForTesting() + let graph = try loadModulesGraph( + fileSystem: fs, + manifests: [ + Manifest.createRootManifest( + displayName: "Pkg", + path: .init(validating: Pkg.pathString), + targets: [ + TargetDescription( + name: "A", + settings: [.init(tool: .swift, kind: .enableExperimentalFeature("Embedded"))] + ), + ] + ), + ], + observabilityScope: observability.topScope + ) + XCTAssertNoDiagnostics(observability.diagnostics) + + // -Xfrontend -mergeable symbols should be passed with Embedded + let result = try await BuildPlanResult(plan: mockBuildPlan( + graph: graph, + fileSystem: fs, + observabilityScope: observability.topScope + )) + result.checkTargetsCount(1) + + // Compile Swift Target + let aCompileArguments = try result.moduleBuildDescription(for: "A").swift().compileArguments() + let aCompileArgumentsPattern: [StringPattern] = ["-Xfrontend", "-mergeable-symbols"] + XCTAssertMatch(aCompileArguments, aCompileArgumentsPattern) } func testREPLArguments() async throws {