diff --git a/Sources/Build/BuildPlan.swift b/Sources/Build/BuildPlan.swift index ddde8985e38..cc17e7edecc 100644 --- a/Sources/Build/BuildPlan.swift +++ b/Sources/Build/BuildPlan.swift @@ -1127,8 +1127,7 @@ public final class SwiftTargetBuildDescription { } private var stdlibArguments: [String] { - if buildParameters.shouldLinkStaticSwiftStdlib && - buildParameters.triple.isSupportingStaticStdlib { + if buildParameters.shouldStaticallyLinkSwiftRuntimeLibrary { return ["-static-stdlib"] } else { return [] @@ -1304,12 +1303,8 @@ public final class ProductBuildDescription { args += deadStripArguments case .executable, .snippet: // Link the Swift stdlib statically, if requested. - if buildParameters.shouldLinkStaticSwiftStdlib { - if buildParameters.triple.isDarwin() { - self.observabilityScope.emit(.swiftBackDeployError) - } else if buildParameters.triple.isSupportingStaticStdlib { - args += ["-static-stdlib"] - } + if buildParameters.shouldStaticallyLinkSwiftRuntimeLibrary { + args += ["-static-stdlib"] } args += ["-emit-executable"] args += deadStripArguments @@ -2284,8 +2279,23 @@ private func generateResourceInfoPlist( return true } -fileprivate extension TSCUtility.Triple { - var isSupportingStaticStdlib: Bool { +extension BuildParameters { + fileprivate var shouldStaticallyLinkSwiftRuntimeLibrary: Bool { + guard !self.disableAutomaticSwiftRuntimeStaticLinking else { + return false + } + guard self.triple.isSupportingStaticStdlib else { + return false + } + guard self.configuration == .release else { + return false + } + return true + } +} + +extension TSCUtility.Triple { + fileprivate var isSupportingStaticStdlib: Bool { isLinux() || arch == .wasm32 } } diff --git a/Sources/Commands/Options.swift b/Sources/Commands/Options.swift index e9e68802144..059336e0e53 100644 --- a/Sources/Commands/Options.swift +++ b/Sources/Commands/Options.swift @@ -200,7 +200,6 @@ struct ResolverOptions: ParsableArguments { @Flag(name: .customLong("skip-update"), help: "Skip updating dependencies from their remote during a resolution") var skipDependencyUpdate: Bool = false - @Flag(help: "Define automatic transformation of source control based dependencies to registry based ones") var sourceControlToRegistryDependencyTransformation: SourceControlToRegistryDependencyTransformation = .disabled @@ -387,9 +386,13 @@ struct LinkerOptions: ParsableArguments { help: "Disable/enable dead code stripping by the linker") var linkerDeadStrip: Bool = true + /// If should link the Swift runtime libraries (stdlib, foundation, dispatch, etc) statically. + @Flag(name: .customLong("disable-static-swift-runtime"), help: "Disable static linking of the Swift runtime libraries (which is done automatically on supported platforms like Linux)") + var disableAutomaticSwiftRuntimeStaticLinking: Bool = false + /// If should link the Swift stdlib statically. - @Flag(name: .customLong("static-swift-stdlib"), inversion: .prefixedNo, help: "Link Swift stdlib statically") - var shouldLinkStaticSwiftStdlib: Bool = false + @Flag(name: .customLong("static-swift-stdlib"), inversion: .prefixedNo, help: .hidden) + var _deprecated_shouldLinkStaticSwiftStdlib: Bool? } diff --git a/Sources/Commands/SwiftTool.swift b/Sources/Commands/SwiftTool.swift index 95269c7c095..b8f41201198 100644 --- a/Sources/Commands/SwiftTool.swift +++ b/Sources/Commands/SwiftTool.swift @@ -536,6 +536,10 @@ public class SwiftTool { if options.caching._deprecated_useRepositoriesCache != nil { observabilityScope.emit(warning: "'--disable-repository-cache'/'--enable-repository-cache' flags are deprecated; use '--disable-dependency-cache'/'--enable-dependency-cache' instead") } + + if options.linker._deprecated_shouldLinkStaticSwiftStdlib != nil { + observabilityScope.emit(warning: "'--shouldLinkStaticSwiftStdlib' option is deprecated; Statically linking the Swift runtime is automatically done on relevant platforms (eg Linux). You may opt out of this behavior with --disable-static-swift-runtime") + } } /// Returns the currently active workspace. @@ -678,7 +682,7 @@ public class SwiftTool { throw error } } - + func getPluginScriptRunner(customPluginsDir: AbsolutePath? = .none) throws -> PluginScriptRunner { let pluginsDir = try customPluginsDir ?? self.getActiveWorkspace().location.pluginWorkingDirectory let cacheDir = pluginsDir.appending(component: "cache") @@ -819,7 +823,8 @@ public class SwiftTool { // can be used to build for any Apple platform and it has it's own // conventions for build subpaths based on platforms. let dataPath = self.scratchDirectory.appending( - component: options.build.buildSystem == .xcode ? "apple" : triple.platformBuildPathComponent()) + component: options.build.buildSystem == .xcode ? "apple" : triple.platformBuildPathComponent() + ) return BuildParameters( dataPath: dataPath, configuration: options.build.configuration, @@ -829,7 +834,7 @@ public class SwiftTool { flags: options.build.buildFlags, xcbuildFlags: options.build.xcbuildFlags, jobs: options.build.jobs ?? UInt32(ProcessInfo.processInfo.activeProcessorCount), - shouldLinkStaticSwiftStdlib: options.linker.shouldLinkStaticSwiftStdlib, + disableAutomaticSwiftRuntimeStaticLinking: options.linker.disableAutomaticSwiftRuntimeStaticLinking, canRenameEntrypointFunctionName: SwiftTargetBuildDescription.checkSupportedFrontendFlags( flags: ["entry-point-function-name"], fileSystem: self.fileSystem ), diff --git a/Sources/SPMBuildCore/BuildParameters.swift b/Sources/SPMBuildCore/BuildParameters.swift index 0c7e7bc892e..4a08b3a72bb 100644 --- a/Sources/SPMBuildCore/BuildParameters.swift +++ b/Sources/SPMBuildCore/BuildParameters.swift @@ -97,8 +97,8 @@ public struct BuildParameters: Encodable { /// How many jobs should llbuild and the Swift compiler spawn public var jobs: UInt32 - /// If should link the Swift stdlib statically. - public var shouldLinkStaticSwiftStdlib: Bool + /// Disable automatic statically link the Swift runtime on supported platforms. + public var disableAutomaticSwiftRuntimeStaticLinking: Bool /// Which compiler sanitizers should be enabled public var sanitizers: EnabledSanitizers @@ -188,7 +188,7 @@ public struct BuildParameters: Encodable { flags: BuildFlags, xcbuildFlags: [String] = [], jobs: UInt32 = UInt32(ProcessInfo.processInfo.activeProcessorCount), - shouldLinkStaticSwiftStdlib: Bool = false, + disableAutomaticSwiftRuntimeStaticLinking: Bool = false, shouldEnableManifestCaching: Bool = false, canRenameEntrypointFunctionName: Bool = false, shouldCreateDylibForDynamicProducts: Bool = true, @@ -218,7 +218,7 @@ public struct BuildParameters: Encodable { self.flags = flags self.xcbuildFlags = xcbuildFlags self.jobs = jobs - self.shouldLinkStaticSwiftStdlib = shouldLinkStaticSwiftStdlib + self.disableAutomaticSwiftRuntimeStaticLinking = disableAutomaticSwiftRuntimeStaticLinking self.shouldEnableManifestCaching = shouldEnableManifestCaching self.shouldCreateDylibForDynamicProducts = shouldCreateDylibForDynamicProducts self.canRenameEntrypointFunctionName = canRenameEntrypointFunctionName diff --git a/Tests/BuildTests/BuildPlanTests.swift b/Tests/BuildTests/BuildPlanTests.swift index de3ffa44d7a..6ea8a16ad10 100644 --- a/Tests/BuildTests/BuildPlanTests.swift +++ b/Tests/BuildTests/BuildPlanTests.swift @@ -67,7 +67,7 @@ final class BuildPlanTests: XCTestCase { config: BuildConfiguration = .debug, toolchain: PackageModel.Toolchain = MockToolchain(), flags: BuildFlags = BuildFlags(), - shouldLinkStaticSwiftStdlib: Bool = false, + disableAutomaticSwiftRuntimeStaticLinking: Bool = false, canRenameEntrypointFunctionName: Bool = false, destinationTriple: TSCUtility.Triple = hostTriple, indexStoreMode: BuildParameters.IndexStoreMode = .off, @@ -82,7 +82,7 @@ final class BuildPlanTests: XCTestCase { destinationTriple: destinationTriple, flags: flags, jobs: 3, - shouldLinkStaticSwiftStdlib: shouldLinkStaticSwiftStdlib, + disableAutomaticSwiftRuntimeStaticLinking: disableAutomaticSwiftRuntimeStaticLinking, canRenameEntrypointFunctionName: canRenameEntrypointFunctionName, indexStoreMode: indexStoreMode, useExplicitModuleBuild: useExplicitModuleBuild, @@ -131,7 +131,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -146,7 +146,7 @@ final class BuildPlanTests: XCTestCase { let lib = try result.target(for: "lib").swiftTarget().compileArguments() XCTAssertMatch(lib, ["-swift-version", "4", "-enable-batch-mode", "-Onone", "-enable-testing", "-g", .equal(j), "-DSWIFT_PACKAGE", "-DDEBUG", "-module-cache-path", "/path/to/build/debug/ModuleCache", .anySequence]) - #if os(macOS) + #if os(macOS) let linkArguments = [ "/fake/path/to/swiftc", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/exe", "-module-name", "exe", @@ -158,26 +158,19 @@ final class BuildPlanTests: XCTestCase { "-Xlinker", "/path/to/build/debug/exe.build/exe.swiftmodule", "-Xlinker", "-add_ast_path", "-Xlinker", "/path/to/build/debug/lib.swiftmodule", ] - #else + #else let linkArguments = [ "/fake/path/to/swiftc", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/exe", "-module-name", "exe", - "-static-stdlib", "-emit-executable", + "-emit-executable", "-Xlinker", "-rpath=$ORIGIN", "@/path/to/build/debug/exe.product/Objects.LinkFileList", "-target", defaultTargetTriple, ] - #endif + #endif XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), linkArguments) - - #if os(macOS) - testDiagnostics(observability.diagnostics) { result in - result.check(diagnostic: .contains("can be downloaded"), severity: .warning) - } - #else XCTAssertNoDiagnostics(observability.diagnostics) - #endif } func testExplicitSwiftPackageBuild() throws { @@ -476,7 +469,7 @@ final class BuildPlanTests: XCTestCase { #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ "/fake/path/to/swiftc", "-g", "-L", "/path/to/build/release", - "-o", "/path/to/build/release/exe", "-module-name", "exe", "-emit-executable", + "-o", "/path/to/build/release/exe", "-module-name", "exe", "-static-stdlib", "-emit-executable", "-Xlinker", "--gc-sections", "-Xlinker", "-rpath=$ORIGIN", "@/path/to/build/release/exe.product/Objects.LinkFileList", "-target", defaultTargetTriple, @@ -529,7 +522,7 @@ final class BuildPlanTests: XCTestCase { #else XCTAssertEqual(try result.buildProduct(for: "exe").linkArguments(), [ "/fake/path/to/swiftc", "-g", "-L", "/path/to/build/release", - "-o", "/path/to/build/release/exe", "-module-name", "exe", "-emit-executable", + "-o", "/path/to/build/release/exe", "-module-name", "exe", "-static-stdlib", "-emit-executable", "-Xlinker", "-rpath=$ORIGIN", "@/path/to/build/release/exe.product/Objects.LinkFileList", "-target", defaultTargetTriple, @@ -1118,7 +1111,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -1834,8 +1827,8 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) - let result = try BuildPlanResult(plan: try BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + let result = try BuildPlanResult(plan: BuildPlan( + buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -1910,8 +1903,8 @@ final class BuildPlanTests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) - let result = try BuildPlanResult(plan: try BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + let result = try BuildPlanResult(plan: BuildPlan( + buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -2040,7 +2033,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: try BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -2122,7 +2115,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: try BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -2229,7 +2222,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: try BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -2334,7 +2327,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: try BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -2445,7 +2438,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: try BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -2557,7 +2550,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: try BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -2634,7 +2627,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: try BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -2720,7 +2713,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertNoDiagnostics(observability.diagnostics) let result = try BuildPlanResult(plan: try BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true), + buildParameters: mockBuildParameters(), graph: graph, fileSystem: fs, observabilityScope: observability.topScope @@ -2906,7 +2899,7 @@ final class BuildPlanTests: XCTestCase { XCTAssertMatch(executablePathExtension, "exe") } - func testWASITarget() throws { + func testWASITargetDebug() throws { let fs = InMemoryFileSystem(emptyFiles: "/Pkg/Sources/app/main.swift", "/Pkg/Sources/lib/lib.c", @@ -2922,8 +2915,8 @@ final class BuildPlanTests: XCTestCase { name: "Pkg", path: .init("/Pkg"), targets: [ - TargetDescription(name: "app", dependencies: ["lib"]), - TargetDescription(name: "lib", dependencies: []), + TargetDescription(name: "app", dependencies: ["lib"], type: .executable), + TargetDescription(name: "lib", dependencies: [], type: .regular), TargetDescription(name: "test", dependencies: ["lib"], type: .test) ] ), @@ -2932,8 +2925,7 @@ final class BuildPlanTests: XCTestCase { ) XCTAssertNoDiagnostics(observability.diagnostics) - var parameters = mockBuildParameters(destinationTriple: .wasi) - parameters.shouldLinkStaticSwiftStdlib = true + let parameters = mockBuildParameters(destinationTriple: .wasi) let result = try BuildPlanResult(plan: BuildPlan( buildParameters: parameters, graph: graph, @@ -2971,7 +2963,7 @@ final class BuildPlanTests: XCTestCase { [ "/fake/path/to/swiftc", "-L", "/path/to/build/debug", "-o", "/path/to/build/debug/app.wasm", - "-module-name", "app", "-static-stdlib", "-emit-executable", + "-module-name", "app", "-emit-executable", "@/path/to/build/debug/app.product/Objects.LinkFileList", "-target", "wasm32-unknown-wasi" ] @@ -2996,6 +2988,96 @@ final class BuildPlanTests: XCTestCase { XCTAssertEqual(testPathExtension, "wasm") } + func testWASITargetRelease() throws { + let fs = InMemoryFileSystem(emptyFiles: + "/Pkg/Sources/app/main.swift", + "/Pkg/Sources/lib/lib.c", + "/Pkg/Sources/lib/include/lib.h", + "/Pkg/Tests/test/TestCase.swift" + ) + + let observability = ObservabilitySystem.makeForTesting() + let graph = try loadPackageGraph( + fileSystem: fs, + manifests: [ + Manifest.createRootManifest( + name: "Pkg", + path: .init("/Pkg"), + targets: [ + TargetDescription(name: "app", dependencies: ["lib"], type: .executable), + TargetDescription(name: "lib", dependencies: [], type: .regular), + TargetDescription(name: "test", dependencies: ["lib"], type: .test) + ] + ), + ], + observabilityScope: observability.topScope + ) + XCTAssertNoDiagnostics(observability.diagnostics) + + let parameters = mockBuildParameters(config: .release, destinationTriple: .wasi) + let result = try BuildPlanResult(plan: BuildPlan( + buildParameters: parameters, + graph: graph, + fileSystem: fs, + observabilityScope: observability.topScope + )) + result.checkProductsCount(2) + result.checkTargetsCount(4) + + let lib = try result.target(for: "lib").clangTarget() + let args = [ + "-target", "wasm32-unknown-wasi", "-g", "-O2", "-DSWIFT_PACKAGE=1", + "-fblocks", "-fmodules", "-fmodule-name=lib", "-I", "/Pkg/Sources/lib/include", + "-fmodules-cache-path=/path/to/build/release/ModuleCache" + ] + XCTAssertEqual(try lib.basicArguments(isCXX: false), args) + XCTAssertEqual(lib.objects, [AbsolutePath("/path/to/build/release/lib.build/lib.c.o")]) + XCTAssertEqual(lib.moduleMap, AbsolutePath("/path/to/build/release/lib.build/module.modulemap")) + + let exe = try result.target(for: "app").swiftTarget().compileArguments() + XCTAssertMatch( + exe, + [ + "-swift-version", "4", "-O", "-g", .equal(j), + "-DSWIFT_PACKAGE", "-Xcc", "-fmodule-map-file=/path/to/build/release/lib.build/module.modulemap", + "-Xcc", "-I", "-Xcc", "/Pkg/Sources/lib/include", + "-module-cache-path", "/path/to/build/release/ModuleCache", .anySequence + ] + ) + + let appBuildDescription = try result.buildProduct(for: "app") + XCTAssertEqual( + try appBuildDescription.linkArguments(), + [ + "/fake/path/to/swiftc", "-g", "-L", "/path/to/build/release", + "-o", "/path/to/build/release/app.wasm", + "-module-name", "app", "-static-stdlib", "-emit-executable", + "-Xlinker", "--gc-sections", + "@/path/to/build/release/app.product/Objects.LinkFileList", + "-target", "wasm32-unknown-wasi" + ] + ) + + let executablePathExtension = appBuildDescription.binary.extension + XCTAssertEqual(executablePathExtension, "wasm") + + let testBuildDescription = try result.buildProduct(for: "PkgPackageTests") + XCTAssertEqual( + try testBuildDescription.linkArguments(), + [ + "/fake/path/to/swiftc", "-g", "-L", "/path/to/build/release", + "-o", "/path/to/build/release/PkgPackageTests.wasm", + "-module-name", "PkgPackageTests", "-emit-executable", + "-Xlinker", "--gc-sections", + "@/path/to/build/release/PkgPackageTests.product/Objects.LinkFileList", + "-target", "wasm32-unknown-wasi" + ] + ) + + let testPathExtension = testBuildDescription.binary.extension + XCTAssertEqual(testPathExtension, "wasm") + } + func testEntrypointRenaming() throws { let fs = InMemoryFileSystem(emptyFiles: "/Pkg/Sources/exe/main.swift" @@ -3875,7 +3957,7 @@ final class BuildPlanTests: XCTestCase { ]) } - func testShouldLinkStaticSwiftStdlib() throws { + func testShouldLinkStaticSwiftStdlibRelease() throws { let fs = InMemoryFileSystem(emptyFiles: "/Pkg/Sources/exe/main.swift", "/Pkg/Sources/lib/lib.swift" @@ -3890,8 +3972,8 @@ final class BuildPlanTests: XCTestCase { name: "Pkg", path: .init("/Pkg"), targets: [ - TargetDescription(name: "exe", dependencies: ["lib"]), - TargetDescription(name: "lib", dependencies: []), + TargetDescription(name: "exe", dependencies: ["lib"], type: .executable), + TargetDescription(name: "lib", dependencies: [], type: .regular), ]), ], observabilityScope: observability.topScope @@ -3899,19 +3981,38 @@ final class BuildPlanTests: XCTestCase { let supportingTriples: [TSCUtility.Triple] = [.x86_64Linux, .arm64Linux, .wasi] for triple in supportingTriples { - let result = try BuildPlanResult(plan: BuildPlan( - buildParameters: mockBuildParameters(shouldLinkStaticSwiftStdlib: true, destinationTriple: triple), - graph: graph, - fileSystem: fs, - observabilityScope: observability.topScope - )) - - let exe = try result.target(for: "exe").swiftTarget().compileArguments() - XCTAssertMatch(exe, ["-static-stdlib"]) - let lib = try result.target(for: "lib").swiftTarget().compileArguments() - XCTAssertMatch(lib, ["-static-stdlib"]) - let link = try result.buildProduct(for: "exe").linkArguments() - XCTAssertMatch(link, ["-static-stdlib"]) + // should static link in release + do { + let result = try BuildPlanResult(plan: BuildPlan( + buildParameters: mockBuildParameters(config: .release, destinationTriple: triple), + graph: graph, + fileSystem: fs, + observabilityScope: observability.topScope + )) + + let exe = try result.target(for: "exe").swiftTarget().compileArguments() + XCTAssertMatch(exe, ["-static-stdlib"]) + let lib = try result.target(for: "lib").swiftTarget().compileArguments() + XCTAssertMatch(lib, ["-static-stdlib"]) + let link = try result.buildProduct(for: "exe").linkArguments() + XCTAssertMatch(link, ["-static-stdlib"]) + } + // should not static link in debug + do { + let result = try BuildPlanResult(plan: BuildPlan( + buildParameters: mockBuildParameters(config: .debug, destinationTriple: triple), + graph: graph, + fileSystem: fs, + observabilityScope: observability.topScope + )) + + let exe = try result.target(for: "exe").swiftTarget().compileArguments() + XCTAssertNoMatch(exe, ["-static-stdlib"]) + let lib = try result.target(for: "lib").swiftTarget().compileArguments() + XCTAssertNoMatch(lib, ["-static-stdlib"]) + let link = try result.buildProduct(for: "exe").linkArguments() + XCTAssertNoMatch(link, ["-static-stdlib"]) + } } } @@ -4197,7 +4298,7 @@ final class BuildPlanTests: XCTestCase { // Unrealistic: we can't enable all of these at once on all platforms. // This test codifies current behavior, not ideal behavior, and // may need to be amended if we change it. - var parameters = mockBuildParameters(shouldLinkStaticSwiftStdlib: true) + var parameters = mockBuildParameters() parameters.sanitizers = EnabledSanitizers([sanitizer]) let result = try BuildPlanResult(plan: BuildPlan( diff --git a/Utilities/bootstrap b/Utilities/bootstrap index 56428cd750d..0be8ce0213f 100755 --- a/Utilities/bootstrap +++ b/Utilities/bootstrap @@ -616,6 +616,10 @@ def build_swiftpm_with_swiftpm(args, integrated_swift_driver): if integrated_swift_driver: swiftpm_args.append("--use-integrated-swift-driver") + + # tools distributed in the toolchain should not statically link the swift runtime + swiftpm_args.append("--disable-static-swift-runtime") + # Build SwiftPM, including libSwiftPM, all the command line tools, and the current variant of PackageDescription. call_swiftpm(args, swiftpm_args)