diff --git a/Sources/SWBCore/DependencyResolution.swift b/Sources/SWBCore/DependencyResolution.swift index 803430918..9848aada5 100644 --- a/Sources/SWBCore/DependencyResolution.swift +++ b/Sources/SWBCore/DependencyResolution.swift @@ -206,7 +206,17 @@ struct SpecializationParameters: Hashable, CustomStringConvertible { func imposed(on parameters: BuildParameters, workspaceContext: WorkspaceContext) -> BuildParameters { var overrides = parameters.overrides if let sdkRoot { - overrides["SDKROOT"] = sdkRoot + // The sdkCanonicalName from a Platform is not guaranteed to be available + let defaultSDKAvailable: Bool + do { + let foundSDK = try workspaceContext.core.sdkRegistry.lookup(sdkRoot, activeRunDestination: parameters.activeRunDestination) + defaultSDKAvailable = foundSDK != nil + } catch { + defaultSDKAvailable = false + } + if defaultSDKAvailable { + overrides["SDKROOT"] = sdkRoot + } } if let sdkVariant { overrides["SDK_VARIANT"] = sdkVariant.name diff --git a/Sources/SWBCore/SwiftSDK.swift b/Sources/SWBCore/SwiftSDK.swift index c8f7f43f8..d695b3df6 100644 --- a/Sources/SWBCore/SwiftSDK.swift +++ b/Sources/SWBCore/SwiftSDK.swift @@ -52,13 +52,10 @@ public struct SwiftSDK: Sendable { /// Target-specific properties for this SDK. public let targetTriples: [String: TripleProperties] - init?(identifier: String, version: String, path: Path, fs: any FSProxy) throws { + init?(identifier: String, version: String, metadataPath: Path, fs: any FSProxy) throws { self.identifier = identifier self.version = version - self.path = path - - let metadataPath = path.join("swift-sdk.json") - guard fs.exists(metadataPath) else { return nil } + self.path = metadataPath.dirname let metadataData = try Data(fs.read(metadataPath)) let schema = try JSONDecoder().decode(SchemaVersionInfo.self, from: metadataData) @@ -70,6 +67,8 @@ public struct SwiftSDK: Sendable { /// The default location storing Swift SDKs installed by SwiftPM. static func defaultSwiftSDKsDirectory(hostOperatingSystem: OperatingSystem) throws -> Path { + // NOTE: Keep in sync with SwiftPM's defaultSwiftSDKsDirectory implementation. + // https://github.com/swiftlang/swift-package-manager/blob/deac56dc94d85d28f2f2b5c37ec347ae3523a3fe/Sources/Basics/FileSystem/FileSystem%2BExtensions.swift#L492 let spmURL: URL if hostOperatingSystem == .macOS { spmURL = try FileManager.default.url( @@ -79,7 +78,11 @@ public struct SwiftSDK: Sendable { create: false ).appendingPathComponent("org.swift.swiftpm") } else { - spmURL = URL.homeDirectory.appendingPathComponent(".swiftpm") + if let configurationDirectory = Environment.current["XDG_CONFIG_HOME"] { + spmURL = URL(fileURLWithPath: configurationDirectory, isDirectory: true).appendingPathComponent("swiftpm") + } else { + spmURL = URL.homeDirectory.appendingPathComponent(".swiftpm") + } } return try spmURL.appendingPathComponent("swift-sdks").filePath } @@ -137,13 +140,20 @@ public struct SwiftSDK: Sendable { for (identifier, artifact) in info.artifacts { for variant in artifact.variants { - let sdkPath = artifactBundle.join(variant.path) - guard fs.isDirectory(sdkPath) else { continue } + // A variant's path may be a directory or a file. If it's a directory, we assume it + // contains a swift-sdk.json file. If it's a file, we use it directly as a Swift SDK + // metadata file. + var sdkPath = artifactBundle.join(variant.path) + if sdkPath.fileExtension != "json" && fs.isDirectory(sdkPath) { + sdkPath = sdkPath.join("swift-sdk.json") + } + + guard fs.exists(sdkPath) else { continue } // FIXME: For now, we only support SDKs that are compatible with any host triple. guard variant.supportedTriples?.isEmpty ?? true else { continue } - guard let sdk = try SwiftSDK(identifier: identifier, version: artifact.version, path: sdkPath, fs: fs) else { continue } + guard let sdk = try SwiftSDK(identifier: identifier, version: artifact.version, metadataPath: sdkPath, fs: fs) else { continue } // Filter out SDKs that don't support any of the target triples. if let targetTriples { guard targetTriples.contains(where: { sdk.targetTriples[$0] != nil }) else { continue } diff --git a/Sources/SWBWebAssemblyPlatform/Plugin.swift b/Sources/SWBWebAssemblyPlatform/Plugin.swift index dbc99e82f..edae8d63c 100644 --- a/Sources/SWBWebAssemblyPlatform/Plugin.swift +++ b/Sources/SWBWebAssemblyPlatform/Plugin.swift @@ -106,10 +106,6 @@ struct WebAssemblySDKRegistryExtension: SDKRegistryExtension { "LLVM_TARGET_TRIPLE_OS_VERSION": .plString(os), "SWIFT_LIBRARY_PATH": .plString(swiftResourceDir.join("wasi").str), "SWIFT_RESOURCE_DIR": .plString(swiftResourceDir.str), - // HACK: Ld step does not use swiftc as linker driver but instead uses clang, so we need to add some Swift specific flags - // assuming static linking. - // Tracked in https://github.com/swiftlang/swift-build/issues/3 - "OTHER_LDFLAGS": .plArray(["-lc++", "-lc++abi", "-resource-dir", "$(SWIFT_RESOURCE_DIR)/clang", "@$(SWIFT_LIBRARY_PATH)/static-executable-args.lnk"]), ]), "SupportedTargets": .plDict([ "webassembly": .plDict([ diff --git a/Sources/SWBWebAssemblyPlatform/Specs/WasmLd.xcspec b/Sources/SWBWebAssemblyPlatform/Specs/WasmLd.xcspec index ba1061724..2fb21519b 100644 --- a/Sources/SWBWebAssemblyPlatform/Specs/WasmLd.xcspec +++ b/Sources/SWBWebAssemblyPlatform/Specs/WasmLd.xcspec @@ -148,6 +148,30 @@ Type = Path; Condition = "NO"; // wasm-ld does not support -filelist }, + { + Name = "SWIFTC_LINKER_RESOURCE_DIR"; + Type = Path; + DefaultValue = "$(SWIFT_RESOURCE_DIR)"; + Condition = "$(LINKER_DRIVER) == swiftc"; + CommandLineArgs = ( + "-resource-dir", + "$(value)", + "-Xclang-linker", + "-resource-dir", + "-Xclang-linker", + "$(value)/clang", + ); + IsInputDependency = Yes; + }, + // TODO(yuta): Remove this override entry after https://github.com/swiftlang/swift-driver/pull/2053 + { + Name = SWIFTC_SDKROOT_LINKER_INPUT; + Type = Path; + DefaultValue = "$(SYSROOT:default=$(SDKROOT))"; + Condition = "$(LINKER_DRIVER) == swiftc"; + CommandLineFlag = "-sdk"; + IsInputDependency = Yes; + }, ); }, )