diff --git a/.swift-version b/.swift-version index 4ac4fded49f..d716112bbc1 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -6.2.0 \ No newline at end of file +6.2.3 \ No newline at end of file diff --git a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift index 5e5b95908cf..7c001e453ad 100644 --- a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift @@ -265,6 +265,8 @@ public struct SwiftSDK: Equatable { /// deserialization. public private(set) var toolset: Toolset + public private(set) var swiftSDKManifest: Basics.AbsolutePath? + /// The paths associated with a Swift SDK. The Path type can be a `String` /// to encapsulate the arguments for the `SwiftSDKConfigurationStore.configure` /// function, or can be a fully-realized `AbsolutePath` when deserialized from a configuration. @@ -499,12 +501,14 @@ public struct SwiftSDK: Equatable { hostTriple: Triple? = nil, targetTriple: Triple? = nil, toolset: Toolset, + swiftSDKManifest: Basics.AbsolutePath? = nil, pathsConfiguration: PathsConfiguration, xctestSupport: XCTestSupport = .supported ) { self.hostTriple = hostTriple self.targetTriple = targetTriple self.toolset = toolset + self.swiftSDKManifest = swiftSDKManifest self.pathsConfiguration = pathsConfiguration self.xctestSupport = xctestSupport } @@ -942,7 +946,8 @@ extension SwiftSDK { targetTriple: triple, properties: properties, toolset: toolset, - swiftSDKDirectory: swiftSDKDirectory + swiftSDKDirectory: swiftSDKDirectory, + swiftSDKManifest: path, ) } @@ -973,7 +978,8 @@ extension SwiftSDK { targetTriple: triple, properties: properties, toolset: toolset, - swiftSDKDirectory: swiftSDKDirectory + swiftSDKDirectory: swiftSDKDirectory, + swiftSDKManifest: path, ) } default: @@ -991,11 +997,13 @@ extension SwiftSDK { targetTriple: Triple, properties: SwiftSDKMetadataV4.TripleProperties, toolset: Toolset = .init(), - swiftSDKDirectory: Basics.AbsolutePath? = nil + swiftSDKDirectory: Basics.AbsolutePath? = nil, + swiftSDKManifest: Basics.AbsolutePath? = nil, ) throws { self.init( targetTriple: targetTriple, toolset: toolset, + swiftSDKManifest: swiftSDKManifest, pathsConfiguration: try .init(properties, swiftSDKDirectory: swiftSDKDirectory) ) } @@ -1010,11 +1018,13 @@ extension SwiftSDK { targetTriple: Triple, properties: SerializedDestinationV3.TripleProperties, toolset: Toolset = .init(), - swiftSDKDirectory: Basics.AbsolutePath? = nil + swiftSDKDirectory: Basics.AbsolutePath? = nil, + swiftSDKManifest: Basics.AbsolutePath? = nil, ) throws { self.init( targetTriple: targetTriple, toolset: toolset, + swiftSDKManifest: swiftSDKManifest, pathsConfiguration: try .init(properties, swiftSDKDirectory: swiftSDKDirectory) ) } diff --git a/Sources/PackageModel/Toolchain.swift b/Sources/PackageModel/Toolchain.swift index b6d5a3f478e..d70a22ed21a 100644 --- a/Sources/PackageModel/Toolchain.swift +++ b/Sources/PackageModel/Toolchain.swift @@ -75,6 +75,8 @@ public protocol Toolchain { /// Additional flags to be passed to the C++ compiler. @available(*, deprecated, message: "use extraFlags.cxxCompilerFlags instead") var extraCPPFlags: [String] { get } + + var swiftSDK: SwiftSDK { get } } extension Toolchain { diff --git a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift index c7478c58aee..7d471291605 100644 --- a/Sources/SwiftBuildSupport/SwiftBuildSystem.swift +++ b/Sources/SwiftBuildSupport/SwiftBuildSystem.swift @@ -703,36 +703,45 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem { } private func makeRunDestination() -> SwiftBuild.SWBRunDestinationInfo { - let platformName: String - let sdkName: String - if self.buildParameters.triple.isAndroid() { - // Android triples are identified by the environment part of the triple - platformName = "android" - sdkName = platformName - } else if self.buildParameters.triple.isWasm { - // Swift Build uses webassembly instead of wasi as the platform name - platformName = "webassembly" - sdkName = platformName + if let sdkManifestPath = self.buildParameters.toolchain.swiftSDK.swiftSDKManifest { + return SwiftBuild.SWBRunDestinationInfo( + buildTarget: .swiftSDK(sdkManifestPath: sdkManifestPath.pathString, triple: self.buildParameters.triple.tripleString), + targetArchitecture: buildParameters.triple.archName, + supportedArchitectures: [], + disableOnlyActiveArch: (buildParameters.architectures?.count ?? 1) > 1, + ) } else { - platformName = self.buildParameters.triple.darwinPlatform?.platformName ?? self.buildParameters.triple.osNameUnversioned - sdkName = platformName - } + let platformName: String + let sdkName: String - let sdkVariant: String? - if self.buildParameters.triple.environment == .macabi { - sdkVariant = "iosmac" - } else { - sdkVariant = nil - } + if self.buildParameters.triple.isAndroid() { + // Android triples are identified by the environment part of the triple + platformName = "android" + sdkName = platformName + } else { + platformName = self.buildParameters.triple.darwinPlatform?.platformName ?? self.buildParameters.triple.osNameUnversioned + sdkName = platformName + } - return SwiftBuild.SWBRunDestinationInfo( - platform: platformName, - sdk: sdkName, - sdkVariant: sdkVariant, - targetArchitecture: buildParameters.triple.archName, - supportedArchitectures: [], - disableOnlyActiveArch: (buildParameters.architectures?.count ?? 1) > 1 - ) + let sdkVariant: String? + if self.buildParameters.triple.environment == .macabi { + sdkVariant = "iosmac" + } else { + sdkVariant = nil + } + + return SwiftBuild.SWBRunDestinationInfo( + buildTarget: .toolchainSDK( + platform: platformName, + sdk: sdkName, + sdkVariant: sdkVariant + ), + targetArchitecture: buildParameters.triple.archName, + supportedArchitectures: [], + disableOnlyActiveArch: (buildParameters.architectures?.count ?? 1) > 1, + hostTargetedPlatform: nil + ) + } } internal func makeBuildParameters( @@ -867,12 +876,19 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem { + buildParameters.flags.swiftCompilerFlags.map { $0.shellEscaped() } ).joined(separator: " ") - settings["OTHER_LDFLAGS"] = ( - verboseFlag + // clang will be invoked to link so the verbose flag is valid for it - ["$(inherited)"] - + buildParameters.toolchain.extraFlags.linkerFlags.asSwiftcLinkerFlags().map { $0.shellEscaped() } - + buildParameters.flags.linkerFlags.asSwiftcLinkerFlags().map { $0.shellEscaped() } - ).joined(separator: " ") + let inherited = ["$(inherited)"] + + let buildParametersLinkFlags = + buildParameters.toolchain.extraFlags.linkerFlags.asSwiftcLinkerFlags().map { $0.shellEscaped() } + + buildParameters.flags.linkerFlags.asSwiftcLinkerFlags().map { $0.shellEscaped() } + + var otherLdFlags = + verboseFlag // clang will be invoked to link so the verbose flag is valid for it + + inherited + + otherLdFlags += buildParametersLinkFlags + + settings["OTHER_LDFLAGS"] = otherLdFlags.joined(separator: " ") // Optionally also set the list of architectures to build for. if let architectures = buildParameters.architectures, !architectures.isEmpty { diff --git a/Sources/_InternalBuildTestSupport/MockBuildTestHelper.swift b/Sources/_InternalBuildTestSupport/MockBuildTestHelper.swift index 8354b6e19ce..2b2857d5f4c 100644 --- a/Sources/_InternalBuildTestSupport/MockBuildTestHelper.swift +++ b/Sources/_InternalBuildTestSupport/MockBuildTestHelper.swift @@ -28,7 +28,7 @@ import Testing public func mockBuildPlan( buildPath: AbsolutePath? = nil, environment: BuildEnvironment, - toolchain: PackageModel.Toolchain = MockToolchain(), + toolchain: PackageModel.Toolchain = try! MockToolchain(), graph: ModulesGraph, commonFlags: PackageModel.BuildFlags = .init(), indexStoreMode: BuildParameters.IndexStoreMode = .off, @@ -61,7 +61,7 @@ public func mockBuildPlan( config: BuildConfiguration = .debug, triple: Basics.Triple? = nil, platform: PackageModel.Platform? = nil, - toolchain: PackageModel.Toolchain = MockToolchain(), + toolchain: PackageModel.Toolchain = try! MockToolchain(), graph: ModulesGraph, commonFlags: PackageModel.BuildFlags = .init(), indexStoreMode: BuildParameters.IndexStoreMode = .off, diff --git a/Sources/_InternalTestSupport/MockBuildTestHelper.swift b/Sources/_InternalTestSupport/MockBuildTestHelper.swift index 0648ff1b89a..dfbb47163be 100644 --- a/Sources/_InternalTestSupport/MockBuildTestHelper.swift +++ b/Sources/_InternalTestSupport/MockBuildTestHelper.swift @@ -41,6 +41,7 @@ public struct MockToolchain: PackageModel.Toolchain { public let swiftPMLibrariesLocation = ToolchainConfiguration.SwiftPMLibrariesLocation( manifestLibraryPath: AbsolutePath("/fake/manifestLib/path"), pluginLibraryPath: AbsolutePath("/fake/pluginLibrary/path") ) + public var swiftSDK: PackageModel.SwiftSDK public func getClangCompiler() throws -> AbsolutePath { "/fake/path/to/clang" @@ -54,10 +55,11 @@ public struct MockToolchain: PackageModel.Toolchain { #endif } - public init(swiftResourcesPath: AbsolutePath? = nil) { + public init(swiftResourcesPath: AbsolutePath? = nil) throws { self.swiftResourcesPath = swiftResourcesPath self.metalToolchainPath = nil self.metalToolchainId = nil + self.swiftSDK = try .hostSwiftSDK() } } @@ -84,7 +86,7 @@ public func mockBuildParameters( destination: BuildParameters.Destination, buildPath: AbsolutePath? = nil, config: BuildConfiguration = .debug, - toolchain: PackageModel.Toolchain = MockToolchain(), + toolchain: PackageModel.Toolchain = try! MockToolchain(), flags: PackageModel.BuildFlags = PackageModel.BuildFlags(), buildSystemKind: BuildSystemProvider.Kind = .native, shouldLinkStaticSwiftStdlib: Bool = false, diff --git a/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift b/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift index 493f3db64df..6f0f64ad283 100644 --- a/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift +++ b/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift @@ -26,7 +26,7 @@ final class ClangTargetBuildDescriptionTests: XCTestCase { } func testSwiftCorelibsFoundationIncludeWorkaround() throws { - let toolchain = MockToolchain(swiftResourcesPath: AbsolutePath("/fake/path/lib/swift")) + let toolchain = try MockToolchain(swiftResourcesPath: AbsolutePath("/fake/path/lib/swift")) let macosParameters = mockBuildParameters(destination: .target, toolchain: toolchain, triple: .macOS) let linuxParameters = mockBuildParameters(destination: .target, toolchain: toolchain, triple: .arm64Linux) diff --git a/Tests/PackageModelTests/SwiftSDKTests.swift b/Tests/PackageModelTests/SwiftSDKTests.swift index 999622ee993..37877f3840c 100644 --- a/Tests/PackageModelTests/SwiftSDKTests.swift +++ b/Tests/PackageModelTests/SwiftSDKTests.swift @@ -341,6 +341,7 @@ private let parsedToolsetNoRootDestination = SwiftSDK( ], rootPaths: [] ), + swiftSDKManifest: toolsetNoRootSwiftSDKv4.path, pathsConfiguration: .init( sdkRootPath: bundleRootPath.appending(sdkRootDir), toolsetPaths: ["/tools/otherToolsNoRoot.json"] @@ -359,6 +360,7 @@ private let parsedToolsetRootDestination = SwiftSDK( ], rootPaths: [try! AbsolutePath(validating: "/custom")] ), + swiftSDKManifest: toolsetRootSwiftSDKv4.path, pathsConfiguration: .init( sdkRootPath: bundleRootPath.appending(sdkRootDir), toolsetPaths: ["/tools/someToolsWithRoot.json", "/tools/otherToolsNoRoot.json"] @@ -376,6 +378,7 @@ private let parsedToolsetNoSDKRootPathDestination = SwiftSDK( ], rootPaths: [] ), + swiftSDKManifest: androidWithoutSDKRootPathSwiftSDKv4.path, pathsConfiguration: .init( sdkRootPath: nil, toolsetPaths: ["/tools/otherToolsNoRoot.json"] @@ -455,7 +458,24 @@ final class SwiftSDKTests: XCTestCase { observabilityScope: observability ) - XCTAssertEqual(toolsetNoRootDestinationV3Decoded, [parsedToolsetNoRootDestination]) + let parsedToolsetNoRootDestinationV3 = SwiftSDK( + targetTriple: linuxGNUTargetTriple, + toolset: .init( + knownTools: [ + .librarian: .init(path: try! AbsolutePath(validating: "\(usrBinTools[.librarian]!)")), + .linker: .init(path: try! AbsolutePath(validating: "\(usrBinTools[.linker]!)")), + .debugger: .init(path: try! AbsolutePath(validating: "\(usrBinTools[.debugger]!)")), + ], + rootPaths: [] + ), + swiftSDKManifest: toolsetNoRootDestinationV3.path, + pathsConfiguration: .init( + sdkRootPath: bundleRootPath.appending(sdkRootDir), + toolsetPaths: ["/tools/otherToolsNoRoot.json"] + .map { try! AbsolutePath(validating: $0) } + ) + ) + XCTAssertEqual(toolsetNoRootDestinationV3Decoded, [parsedToolsetNoRootDestinationV3]) let toolsetRootDestinationV3Decoded = try SwiftSDK.decode( fromFile: toolsetRootDestinationV3.path, @@ -464,7 +484,26 @@ final class SwiftSDKTests: XCTestCase { observabilityScope: observability ) - XCTAssertEqual(toolsetRootDestinationV3Decoded, [parsedToolsetRootDestination]) + let parsedToolsetRootDestinationV3Decoded = SwiftSDK( + targetTriple: linuxGNUTargetTriple, + toolset: .init( + knownTools: [ + .cCompiler: .init(extraCLIOptions: cCompilerOptions), + .librarian: .init(path: try! AbsolutePath(validating: "\(usrBinTools[.librarian]!)")), + .linker: .init(path: try! AbsolutePath(validating: "\(usrBinTools[.linker]!)")), + .debugger: .init(path: try! AbsolutePath(validating: "\(usrBinTools[.debugger]!)")), + ], + rootPaths: [try! AbsolutePath(validating: "/custom")] + ), + swiftSDKManifest: toolsetRootDestinationV3.path, + pathsConfiguration: .init( + sdkRootPath: bundleRootPath.appending(sdkRootDir), + toolsetPaths: ["/tools/someToolsWithRoot.json", "/tools/otherToolsNoRoot.json"] + .map { try! AbsolutePath(validating: $0) } + ) + ) + + XCTAssertEqual(toolsetRootDestinationV3Decoded, [parsedToolsetRootDestinationV3Decoded]) XCTAssertThrowsError(try SwiftSDK.decode( fromFile: missingToolsetDestinationV3.path,