From 9aa5ee82f7308b77f10be90fe71e73fe71984954 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Wed, 16 Aug 2023 03:36:45 -0400 Subject: [PATCH 01/25] Implicitly support all Darwin triples on macOS --- Sources/PackageModel/SwiftSDK.swift | 68 ++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/Sources/PackageModel/SwiftSDK.swift b/Sources/PackageModel/SwiftSDK.swift index 657b4e18d55..858dc2b2c9d 100644 --- a/Sources/PackageModel/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDK.swift @@ -449,6 +449,23 @@ public struct SwiftSDK: Equatable { _ binDir: AbsolutePath? = nil, originalWorkingDirectory: AbsolutePath? = nil, environment: [String: String] = ProcessEnv.vars + ) throws -> SwiftSDK { + try self.systemSwiftSDK( + binDir, + originalWorkingDirectory: originalWorkingDirectory, + environment: environment + ) + } + + /// A default Swift SDK on the host. + /// + /// Equivalent to `hostSwiftSDK`, except on macOS, where passing a non-nil `darwinPlatformOverride` + /// will result in the SDK for the corresponding Darwin platform. + private static func systemSwiftSDK( + _ binDir: AbsolutePath? = nil, + originalWorkingDirectory: AbsolutePath? = nil, + environment: [String: String] = ProcessEnv.vars, + darwinPlatformOverride: DarwinPlatform? = nil ) throws -> SwiftSDK { let originalWorkingDirectory = originalWorkingDirectory ?? localFileSystem.currentWorkingDirectory // Select the correct binDir. @@ -464,13 +481,14 @@ public struct SwiftSDK: Equatable { let sdkPath: AbsolutePath? #if os(macOS) + let darwinPlatform = darwinPlatformOverride ?? .macOS // Get the SDK. if let value = lookupExecutablePath(filename: ProcessEnv.vars["SDKROOT"]) { sdkPath = value } else { // No value in env, so search for it. let sdkPathStr = try TSCBasic.Process.checkNonZeroExit( - arguments: ["/usr/bin/xcrun", "--sdk", "macosx", "--show-sdk-path"], + arguments: ["/usr/bin/xcrun", "--sdk", darwinPlatform.xcrunName, "--show-sdk-path"], environment: environment ).spm_chomp() guard !sdkPathStr.isEmpty else { @@ -486,7 +504,7 @@ public struct SwiftSDK: Equatable { var extraCCFlags: [String] = [] var extraSwiftCFlags: [String] = [] #if os(macOS) - let sdkPaths = try SwiftSDK.sdkPlatformFrameworkPaths(environment: environment) + let sdkPaths = try SwiftSDK.sdkPlatformFrameworkPaths(for: darwinPlatform, environment: environment) extraCCFlags += ["-F", sdkPaths.fwk.pathString] extraSwiftCFlags += ["-F", sdkPaths.fwk.pathString] extraSwiftCFlags += ["-I", sdkPaths.lib.pathString] @@ -509,15 +527,16 @@ public struct SwiftSDK: Equatable { ) } - /// Returns `macosx` sdk platform framework path. + /// Returns framework paths for the provided Darwin platform. public static func sdkPlatformFrameworkPaths( + for darwinPlatform: DarwinPlatform = .macOS, environment: EnvironmentVariables = .process() ) throws -> (fwk: AbsolutePath, lib: AbsolutePath) { if let path = _sdkPlatformFrameworkPath { return path } let platformPath = try TSCBasic.Process.checkNonZeroExit( - arguments: ["/usr/bin/xcrun", "--sdk", "macosx", "--show-sdk-platform-path"], + arguments: ["/usr/bin/xcrun", "--sdk", darwinPlatform.platformName, "--show-sdk-platform-path"], environment: environment ).spm_chomp() @@ -547,21 +566,15 @@ public struct SwiftSDK: Equatable { /// Returns a default destination of a given target environment @available(*, deprecated, renamed: "defaultSwiftSDK") public static func defaultDestination(for triple: Triple, host: SwiftSDK) -> SwiftSDK? { - if triple.isWASI() { - let wasiSysroot = host.toolset.rootPaths.first? - .parentDirectory // usr - .appending(components: "share", "wasi-sysroot") - return SwiftSDK( - targetTriple: triple, - toolset: host.toolset, - pathsConfiguration: .init(sdkRootPath: wasiSysroot) - ) - } - return nil + defaultSwiftSDK(for: triple, hostSDK: host) } /// Returns a default Swift SDK of a given target environment. - public static func defaultSwiftSDK(for targetTriple: Triple, hostSDK: SwiftSDK) -> SwiftSDK? { + public static func defaultSwiftSDK( + for targetTriple: Triple, + hostSDK: SwiftSDK, + environment: [String: String] = ProcessEnv.vars + ) -> SwiftSDK? { if targetTriple.isWASI() { let wasiSysroot = hostSDK.toolset.rootPaths.first? .parentDirectory // usr @@ -572,6 +585,17 @@ public struct SwiftSDK: Equatable { pathsConfiguration: .init(sdkRootPath: wasiSysroot) ) } + + #if os(macOS) + if let darwinPlatform = targetTriple.darwinPlatform { + return try? self.systemSwiftSDK( + hostSDK.toolset.rootPaths.first, + environment: environment, + darwinPlatformOverride: darwinPlatform + ) + } + #endif + return nil } @@ -796,6 +820,18 @@ extension SwiftSDK { } } +extension DarwinPlatform { + /// The name xcrun uses to identify this platform. + fileprivate var xcrunName: String { + switch self { + case .iOS(.catalyst): + return "macosx" + default: + return platformName + } + } +} + /// Integer version of the schema of `destination.json` files used for cross-compilation. private struct VersionInfo: Codable { let version: Int From b82a40022fdce31d2349c4da5873c18dd1630fba Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Thu, 17 Aug 2023 23:25:04 -0400 Subject: [PATCH 02/25] comment --- Sources/PackageModel/SwiftSDK.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/PackageModel/SwiftSDK.swift b/Sources/PackageModel/SwiftSDK.swift index 858dc2b2c9d..413fce7cb55 100644 --- a/Sources/PackageModel/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDK.swift @@ -588,6 +588,7 @@ public struct SwiftSDK: Equatable { #if os(macOS) if let darwinPlatform = targetTriple.darwinPlatform { + // the Darwin SDKs are trivially available on macOS return try? self.systemSwiftSDK( hostSDK.toolset.rootPaths.first, environment: environment, From ca0822d76df7667fefadda18c24091010d1cd13d Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Fri, 18 Aug 2023 00:13:06 -0400 Subject: [PATCH 03/25] Fix sdkPlatformFrameworkPath memoization --- Sources/PackageModel/SwiftSDK.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/PackageModel/SwiftSDK.swift b/Sources/PackageModel/SwiftSDK.swift index 413fce7cb55..49b7c12fec3 100644 --- a/Sources/PackageModel/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDK.swift @@ -532,7 +532,7 @@ public struct SwiftSDK: Equatable { for darwinPlatform: DarwinPlatform = .macOS, environment: EnvironmentVariables = .process() ) throws -> (fwk: AbsolutePath, lib: AbsolutePath) { - if let path = _sdkPlatformFrameworkPath { + if let path = _sdkPlatformFrameworkPath[darwinPlatform] { return path } let platformPath = try TSCBasic.Process.checkNonZeroExit( @@ -555,13 +555,13 @@ public struct SwiftSDK: Equatable { ) let sdkPlatformFrameworkPath = (fwk, lib) - _sdkPlatformFrameworkPath = sdkPlatformFrameworkPath + _sdkPlatformFrameworkPath[darwinPlatform] = sdkPlatformFrameworkPath return sdkPlatformFrameworkPath } // FIXME: convert this from a tuple to a proper struct with documented properties /// Cache storage for sdk platform path. - private static var _sdkPlatformFrameworkPath: (fwk: AbsolutePath, lib: AbsolutePath)? = nil + private static var _sdkPlatformFrameworkPath: [DarwinPlatform: (fwk: AbsolutePath, lib: AbsolutePath)] = [:] /// Returns a default destination of a given target environment @available(*, deprecated, renamed: "defaultSwiftSDK") From a20232005b62941c1506caa889fb1c1b75cb1503 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Fri, 18 Aug 2023 00:13:18 -0400 Subject: [PATCH 04/25] Add tests --- Tests/PackageModelTests/SwiftSDKTests.swift | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Tests/PackageModelTests/SwiftSDKTests.swift b/Tests/PackageModelTests/SwiftSDKTests.swift index 08a025a620b..803b1b173ee 100644 --- a/Tests/PackageModelTests/SwiftSDKTests.swift +++ b/Tests/PackageModelTests/SwiftSDKTests.swift @@ -554,4 +554,23 @@ final class DestinationTests: XCTestCase { parsedDestinationV2Musl ) } + + func testDefaultSDKs() throws { + let hostSDK = try SwiftSDK.default + + #if os(macOS) + let iOSTriple = try Triple("arm64-apple-ios") + let iOS = try XCTUnwrap(SwiftSDK.defaultSwiftSDK(for: iOSTriple, hostSDK: hostSDK)) + XCTAssertEqual(iOS.toolset.rootPaths, hostSDK.toolset.rootPaths) + + let sdkPath = try XCTUnwrap(iOS.pathsConfiguration.sdkRootPath) + XCTAssertEqual(sdkPath.extension, "sdk") + + let sdkName = try XCTUnwrap(sdkPath.components.last) + XCTAssert(sdkName.hasPrefix("iPhoneOS")) + + let cFlags = iOS.toolset.knownTools[.cCompiler]?.extraCLIOptions ?? [] + XCTAssertFalse(cFlags.contains { $0.lowercased().contains("macos") }, "Found macOS path in \(cFlags)") + #endif + } } From 46b65d18d7b631d6dabb1b34b64e1010c81cf869 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Fri, 18 Aug 2023 00:16:05 -0400 Subject: [PATCH 05/25] a dash of determinism --- Tests/PackageModelTests/SwiftSDKTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/PackageModelTests/SwiftSDKTests.swift b/Tests/PackageModelTests/SwiftSDKTests.swift index 803b1b173ee..9b16037e1cb 100644 --- a/Tests/PackageModelTests/SwiftSDKTests.swift +++ b/Tests/PackageModelTests/SwiftSDKTests.swift @@ -556,7 +556,7 @@ final class DestinationTests: XCTestCase { } func testDefaultSDKs() throws { - let hostSDK = try SwiftSDK.default + let hostSDK = try SwiftSDK.hostSwiftSDK("/prefix/bin") #if os(macOS) let iOSTriple = try Triple("arm64-apple-ios") From d253fab0b63b52db8700ee296d1ad5c1ea169370 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sat, 19 Aug 2023 19:29:50 -0400 Subject: [PATCH 06/25] Feedback --- .../Commands/Utilities/TestingSupport.swift | 7 ++-- Sources/PackageModel/SwiftSDK.swift | 32 +++++++++++++------ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index c28d41018a4..20c7fafcd38 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -114,10 +114,11 @@ enum TestingSupport { ) // Add the sdk platform path if we have it. If this is not present, we might always end up failing. - let sdkPlatformFrameworksPath = try SwiftSDK.sdkPlatformFrameworkPaths() + // Since XCTestHelper targets macOS, we need the macOS platform paths here. + let sdkPlatformFrameworksPath = try SwiftSDK.sdkPlatformFrameworkPaths(for: .macOS) // appending since we prefer the user setting (if set) to the one we inject - env.appendPath("DYLD_FRAMEWORK_PATH", value: sdkPlatformFrameworksPath.fwk.pathString) - env.appendPath("DYLD_LIBRARY_PATH", value: sdkPlatformFrameworksPath.lib.pathString) + env.appendPath("DYLD_FRAMEWORK_PATH", value: sdkPlatformFrameworksPath.frameworks.pathString) + env.appendPath("DYLD_LIBRARY_PATH", value: sdkPlatformFrameworksPath.libraries.pathString) try TSCBasic.Process.checkNonZeroExit(arguments: args, environment: env) // Read the temporary file's content. diff --git a/Sources/PackageModel/SwiftSDK.swift b/Sources/PackageModel/SwiftSDK.swift index 49b7c12fec3..64d80bc6235 100644 --- a/Sources/PackageModel/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDK.swift @@ -505,10 +505,10 @@ public struct SwiftSDK: Equatable { var extraSwiftCFlags: [String] = [] #if os(macOS) let sdkPaths = try SwiftSDK.sdkPlatformFrameworkPaths(for: darwinPlatform, environment: environment) - extraCCFlags += ["-F", sdkPaths.fwk.pathString] - extraSwiftCFlags += ["-F", sdkPaths.fwk.pathString] - extraSwiftCFlags += ["-I", sdkPaths.lib.pathString] - extraSwiftCFlags += ["-L", sdkPaths.lib.pathString] + extraCCFlags += ["-F", sdkPaths.frameworks.pathString] + extraSwiftCFlags += ["-F", sdkPaths.frameworks.pathString] + extraSwiftCFlags += ["-I", sdkPaths.libraries.pathString] + extraSwiftCFlags += ["-L", sdkPaths.libraries.pathString] #endif #if !os(Windows) @@ -527,11 +527,24 @@ public struct SwiftSDK: Equatable { ) } + /// Auxiliary platform frameworks and libraries. + /// + /// The referenced directories may contain, for example, test support utilities. + /// + /// - SeeAlso: ``sdkPlatformFrameworkPaths(for:environment:)`` + public struct PlatformPaths { + /// Path to the directory containing auxiliary platform frameworks. + public var frameworks: AbsolutePath + + /// Path to the directory containing auxiliary platform libraries. + public var libraries: AbsolutePath + } + /// Returns framework paths for the provided Darwin platform. public static func sdkPlatformFrameworkPaths( - for darwinPlatform: DarwinPlatform = .macOS, + for darwinPlatform: DarwinPlatform, environment: EnvironmentVariables = .process() - ) throws -> (fwk: AbsolutePath, lib: AbsolutePath) { + ) throws -> PlatformPaths { if let path = _sdkPlatformFrameworkPath[darwinPlatform] { return path } @@ -554,14 +567,13 @@ public struct SwiftSDK: Equatable { components: "Developer", "usr", "lib" ) - let sdkPlatformFrameworkPath = (fwk, lib) + let sdkPlatformFrameworkPath = PlatformPaths(frameworks: fwk, libraries: lib) _sdkPlatformFrameworkPath[darwinPlatform] = sdkPlatformFrameworkPath return sdkPlatformFrameworkPath } - // FIXME: convert this from a tuple to a proper struct with documented properties - /// Cache storage for sdk platform path. - private static var _sdkPlatformFrameworkPath: [DarwinPlatform: (fwk: AbsolutePath, lib: AbsolutePath)] = [:] + /// Cache storage for sdk platform paths. + private static var _sdkPlatformFrameworkPath: [DarwinPlatform: PlatformPaths] = [:] /// Returns a default destination of a given target environment @available(*, deprecated, renamed: "defaultSwiftSDK") From ba32e4c4f55ba358010ea7a051c8af5877aa331d Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sat, 19 Aug 2023 19:30:47 -0400 Subject: [PATCH 07/25] We can't run cross-compiled tests yet --- Sources/Commands/Utilities/TestingSupport.swift | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index 20c7fafcd38..778d2b55be7 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -102,6 +102,15 @@ enum TestingSupport { ) throws -> [TestSuite] { // Run the correct tool. #if os(macOS) + let targetTriple = try swiftTool.getTargetToolchain().targetTriple + guard targetTriple.darwinPlatform == .macOS else { + swiftTool.observabilityScope.emit(error: """ + Attempting to run test suite cross-compiled for non-macOS target '\(targetTriple)'; \ + this is currently unsupported. + """) + return [] + } + let data: String = try withTemporaryFile { tempFile in let args = [try Self.xctestHelperPath(swiftTool: swiftTool).pathString, path.pathString, tempFile.path.pathString] var env = try Self.constructTestEnvironment( From b273ba453e4d9700d400b63eb6a36c247f896f0d Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sat, 19 Aug 2023 19:31:24 -0400 Subject: [PATCH 08/25] test suite -> tests --- Sources/Commands/Utilities/TestingSupport.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index 778d2b55be7..a7c8aaf69c3 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -105,7 +105,7 @@ enum TestingSupport { let targetTriple = try swiftTool.getTargetToolchain().targetTriple guard targetTriple.darwinPlatform == .macOS else { swiftTool.observabilityScope.emit(error: """ - Attempting to run test suite cross-compiled for non-macOS target '\(targetTriple)'; \ + Attempting to run tests cross-compiled for non-macOS target '\(targetTriple)'; \ this is currently unsupported. """) return [] From 2f9adad2c8d4a0574aa0725d9f77b062098ae4d8 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sat, 19 Aug 2023 19:58:29 -0400 Subject: [PATCH 09/25] Reintroduce tuple API as deprecated --- Sources/Commands/Utilities/TestingSupport.swift | 6 +++--- Sources/PackageModel/SwiftSDK.swift | 13 +++++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index a7c8aaf69c3..3cb7ef97586 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -124,10 +124,10 @@ enum TestingSupport { // Add the sdk platform path if we have it. If this is not present, we might always end up failing. // Since XCTestHelper targets macOS, we need the macOS platform paths here. - let sdkPlatformFrameworksPath = try SwiftSDK.sdkPlatformFrameworkPaths(for: .macOS) + let sdkPlatformPaths = try SwiftSDK.sdkPlatformPaths(for: .macOS) // appending since we prefer the user setting (if set) to the one we inject - env.appendPath("DYLD_FRAMEWORK_PATH", value: sdkPlatformFrameworksPath.frameworks.pathString) - env.appendPath("DYLD_LIBRARY_PATH", value: sdkPlatformFrameworksPath.libraries.pathString) + env.appendPath("DYLD_FRAMEWORK_PATH", value: sdkPlatformPaths.frameworks.pathString) + env.appendPath("DYLD_LIBRARY_PATH", value: sdkPlatformPaths.libraries.pathString) try TSCBasic.Process.checkNonZeroExit(arguments: args, environment: env) // Read the temporary file's content. diff --git a/Sources/PackageModel/SwiftSDK.swift b/Sources/PackageModel/SwiftSDK.swift index 64d80bc6235..ecc14df913a 100644 --- a/Sources/PackageModel/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDK.swift @@ -504,7 +504,7 @@ public struct SwiftSDK: Equatable { var extraCCFlags: [String] = [] var extraSwiftCFlags: [String] = [] #if os(macOS) - let sdkPaths = try SwiftSDK.sdkPlatformFrameworkPaths(for: darwinPlatform, environment: environment) + let sdkPaths = try SwiftSDK.sdkPlatformPaths(for: darwinPlatform, environment: environment) extraCCFlags += ["-F", sdkPaths.frameworks.pathString] extraSwiftCFlags += ["-F", sdkPaths.frameworks.pathString] extraSwiftCFlags += ["-I", sdkPaths.libraries.pathString] @@ -540,8 +540,17 @@ public struct SwiftSDK: Equatable { public var libraries: AbsolutePath } - /// Returns framework paths for the provided Darwin platform. + /// Returns `macosx` sdk platform framework path. + @available(*, deprecated, message: "use sdkPlatformPaths(for:) instead") public static func sdkPlatformFrameworkPaths( + environment: EnvironmentVariables = .process() + ) throws -> (fwk: AbsolutePath, lib: AbsolutePath) { + let paths = try sdkPlatformPaths(for: .macOS, environment: environment) + return (fwk: paths.frameworks, lib: paths.libraries) + } + + /// Returns ``SwiftSDK/PlatformPaths`` for the provided Darwin platform. + public static func sdkPlatformPaths( for darwinPlatform: DarwinPlatform, environment: EnvironmentVariables = .process() ) throws -> PlatformPaths { From 9e517033bae000fb8e13fc96a78245cc7ff40948 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Mon, 21 Aug 2023 23:50:00 -0400 Subject: [PATCH 10/25] Set targetTriple for systemSwiftSDK The --triple codepath in SwiftTool also sets this but that's happenstance; we don't want defaultSwiftSDK to ever return an SDK with the wrong targetTriple. --- Sources/PackageModel/SwiftSDK.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/PackageModel/SwiftSDK.swift b/Sources/PackageModel/SwiftSDK.swift index ecc14df913a..123549d810f 100644 --- a/Sources/PackageModel/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDK.swift @@ -610,11 +610,13 @@ public struct SwiftSDK: Equatable { #if os(macOS) if let darwinPlatform = targetTriple.darwinPlatform { // the Darwin SDKs are trivially available on macOS - return try? self.systemSwiftSDK( + var sdk = try? self.systemSwiftSDK( hostSDK.toolset.rootPaths.first, environment: environment, darwinPlatformOverride: darwinPlatform ) + sdk?.targetTriple = targetTriple + return sdk } #endif From ed1513ecd9ca766be35117f568145b6054a7af53 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Tue, 22 Aug 2023 00:13:02 -0400 Subject: [PATCH 11/25] Allow default SDKs via --swift-sdk --- Sources/CoreCommands/SwiftTool.swift | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Sources/CoreCommands/SwiftTool.swift b/Sources/CoreCommands/SwiftTool.swift index 35a336daa11..e29ea0f6e7f 100644 --- a/Sources/CoreCommands/SwiftTool.swift +++ b/Sources/CoreCommands/SwiftTool.swift @@ -756,13 +756,24 @@ public final class SwiftTool { { swiftSDK = targetSwiftSDK } else if let swiftSDKSelector = options.build.swiftSDKSelector { - swiftSDK = try SwiftSDKBundle.selectBundle( - fromBundlesAt: sharedSwiftSDKsDirectory, - fileSystem: fileSystem, - matching: swiftSDKSelector, - hostTriple: hostTriple, - observabilityScope: observabilityScope - ) + do { + swiftSDK = try SwiftSDKBundle.selectBundle( + fromBundlesAt: sharedSwiftSDKsDirectory, + fileSystem: fileSystem, + matching: swiftSDKSelector, + hostTriple: hostTriple, + observabilityScope: observabilityScope + ) + } catch { + // If a user-installed bundle for the selector doesn't exist, check if the + // selector is recognized as a default SDK. + if let triple = try? Triple(swiftSDKSelector), + let defaultSDK = SwiftSDK.defaultSwiftSDK(for: triple, hostSDK: hostSwiftSDK) { + swiftSDK = defaultSDK + } else { + throw error + } + } } else { // Otherwise use the host toolchain. swiftSDK = hostSwiftSDK From c62ad425b1ec333a4bbe32f203c89cbd8ed5bf6b Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Fri, 8 Sep 2023 11:46:32 +0530 Subject: [PATCH 12/25] feedback --- Sources/CoreCommands/SwiftTool.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/CoreCommands/SwiftTool.swift b/Sources/CoreCommands/SwiftTool.swift index e29ea0f6e7f..3ca347b387c 100644 --- a/Sources/CoreCommands/SwiftTool.swift +++ b/Sources/CoreCommands/SwiftTool.swift @@ -751,8 +751,8 @@ public final class SwiftTool { } else { return .failure(SwiftSDKError.noSwiftSDKDecoded(customDestination)) } - } else if let triple = options.build.customCompileTriple, - let targetSwiftSDK = SwiftSDK.defaultSwiftSDK(for: triple, hostSDK: hostSwiftSDK) + } else if let targetTriple = options.build.customCompileTriple, + let targetSwiftSDK = SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) { swiftSDK = targetSwiftSDK } else if let swiftSDKSelector = options.build.swiftSDKSelector { @@ -767,8 +767,8 @@ public final class SwiftTool { } catch { // If a user-installed bundle for the selector doesn't exist, check if the // selector is recognized as a default SDK. - if let triple = try? Triple(swiftSDKSelector), - let defaultSDK = SwiftSDK.defaultSwiftSDK(for: triple, hostSDK: hostSwiftSDK) { + if let targetTriple = try? Triple(swiftSDKSelector), + let defaultSDK = SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) { swiftSDK = defaultSDK } else { throw error From c7c6e4fd358daebb6557d9fa6c0f527c8dfdd645 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Tue, 27 Aug 2024 23:42:19 -0400 Subject: [PATCH 13/25] fixup --- .../Commands/Utilities/TestingSupport.swift | 10 +- Sources/CoreCommands/SwiftCommandState.swift | 116 ++++++++++++------ Sources/PackageModel/SwiftSDKs/SwiftSDK.swift | 34 +++-- 3 files changed, 108 insertions(+), 52 deletions(-) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index 53d060db756..63b3e48aee6 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -111,9 +111,9 @@ enum TestingSupport { // Run the correct tool. var args = [String]() #if os(macOS) - let targetTriple = try swiftTool.getTargetToolchain().targetTriple + let targetTriple = try swiftCommandState.getTargetToolchain().targetTriple guard targetTriple.darwinPlatform == .macOS else { - swiftTool.observabilityScope.emit(error: """ + swiftCommandState.observabilityScope.emit(error: """ Attempting to run tests cross-compiled for non-macOS target '\(targetTriple)'; \ this is currently unsupported. """) @@ -122,7 +122,7 @@ enum TestingSupport { let data: String = try withTemporaryFile { tempFile in args = [try Self.xctestHelperPath(swiftCommandState: swiftCommandState).pathString, path.pathString, tempFile.path.pathString] - let env = try Self.constructTestEnvironment( + var env = try Self.constructTestEnvironment( toolchain: try swiftCommandState.getTargetToolchain(), destinationBuildParameters: swiftCommandState.buildParametersForTest( enableCodeCoverage: enableCodeCoverage, @@ -137,8 +137,8 @@ enum TestingSupport { // Since XCTestHelper targets macOS, we need the macOS platform paths here. let sdkPlatformPaths = try SwiftSDK.sdkPlatformPaths(for: .macOS) // appending since we prefer the user setting (if set) to the one we inject - env.appendPath("DYLD_FRAMEWORK_PATH", value: sdkPlatformPaths.frameworks.pathString) - env.appendPath("DYLD_LIBRARY_PATH", value: sdkPlatformPaths.libraries.pathString) + env.appendPath(key: "DYLD_FRAMEWORK_PATH", value: sdkPlatformPaths.frameworks.pathString) + env.appendPath(key: "DYLD_LIBRARY_PATH", value: sdkPlatformPaths.libraries.pathString) try AsyncProcess.checkNonZeroExit(arguments: args, environment: env) // Read the temporary file's content. diff --git a/Sources/CoreCommands/SwiftCommandState.swift b/Sources/CoreCommands/SwiftCommandState.swift index 1eb9324fb83..44856589668 100644 --- a/Sources/CoreCommands/SwiftCommandState.swift +++ b/Sources/CoreCommands/SwiftCommandState.swift @@ -878,42 +878,6 @@ public final class SwiftCommandState { self.observabilityScope.emit( warning: "`--experimental-swift-sdk` is deprecated and will be removed in a future version of SwiftPM. Use `--swift-sdk` instead." ) - if swiftSDKs.count == 1 { - swiftSDK = swiftSDKs[0] - } else if swiftSDKs.count > 1, - let triple = options.build.customCompileTriple, - let matchingSDK = swiftSDKs.first(where: { $0.targetTriple == triple }) - { - swiftSDK = matchingSDK - } else { - return .failure(SwiftSDKError.noSwiftSDKDecoded(customDestination)) - } - } else if let targetTriple = options.build.customCompileTriple, - let targetSwiftSDK = SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) - { - swiftSDK = targetSwiftSDK - } else if let swiftSDKSelector = options.build.swiftSDKSelector { - do { - swiftSDK = try SwiftSDKBundle.selectBundle( - fromBundlesAt: sharedSwiftSDKsDirectory, - fileSystem: fileSystem, - matching: swiftSDKSelector, - hostTriple: hostTriple, - observabilityScope: observabilityScope - ) - } catch { - // If a user-installed bundle for the selector doesn't exist, check if the - // selector is recognized as a default SDK. - if let targetTriple = try? Triple(swiftSDKSelector), - let defaultSDK = SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) { - swiftSDK = defaultSDK - } else { - throw error - } - } - } else { - // Otherwise use the host toolchain. - swiftSDK = hostSwiftSDK } swiftSDK = try SwiftSDK.deriveTargetSwiftSDK( hostSwiftSDK: hostSwiftSDK, @@ -941,6 +905,86 @@ public final class SwiftCommandState { }) }() +// private lazy var _targetToolchain: Result = { +// let swiftSDK: SwiftSDK +// let hostSwiftSDK: SwiftSDK +// let store = SwiftSDKBundleStore( +// swiftSDKsDirectory: self.sharedSwiftSDKsDirectory, +// fileSystem: fileSystem, +// observabilityScope: observabilityScope, +// outputHandler: { print($0.description) } +// ) +// do { +// let hostToolchain = try _hostToolchain.get() +// hostSwiftSDK = hostToolchain.swiftSDK +// +// if options.build.deprecatedSwiftSDKSelector != nil { +// self.observabilityScope.emit( +// warning: "`--experimental-swift-sdk` is deprecated and will be removed in a future version of SwiftPM. Use `--swift-sdk` instead." +// ) +// if swiftSDKs.count == 1 { +// swiftSDK = swiftSDKs[0] +// } else if swiftSDKs.count > 1, +// let triple = options.build.customCompileTriple, +// let matchingSDK = swiftSDKs.first(where: { $0.targetTriple == triple }) +// { +// swiftSDK = matchingSDK +// } else { +// return .failure(SwiftSDKError.noSwiftSDKDecoded(customDestination)) +// } +// } else if let targetTriple = options.build.customCompileTriple, +// let targetSwiftSDK = SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) +// { +// swiftSDK = targetSwiftSDK +// } else if let swiftSDKSelector = options.build.swiftSDKSelector { +// do { +// swiftSDK = try SwiftSDKBundle.selectBundle( +// fromBundlesAt: sharedSwiftSDKsDirectory, +// fileSystem: fileSystem, +// matching: swiftSDKSelector, +// hostTriple: hostTriple, +// observabilityScope: observabilityScope +// ) +// } catch { +// // If a user-installed bundle for the selector doesn't exist, check if the +// // selector is recognized as a default SDK. +// if let targetTriple = try? Triple(swiftSDKSelector), +// let defaultSDK = SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) { +// swiftSDK = defaultSDK +// } else { +// throw error +// } +// } +// } else { +// // Otherwise use the host toolchain. +// swiftSDK = hostSwiftSDK +// } +// swiftSDK = try SwiftSDK.deriveTargetSwiftSDK( +// hostSwiftSDK: hostSwiftSDK, +// hostTriple: hostToolchain.targetTriple, +// customCompileDestination: options.locations.customCompileDestination, +// customCompileTriple: options.build.customCompileTriple, +// customCompileToolchain: options.build.customCompileToolchain, +// customCompileSDK: options.build.customCompileSDK, +// swiftSDKSelector: options.build.swiftSDKSelector ?? options.build.deprecatedSwiftSDKSelector, +// architectures: options.build.architectures, +// store: store, +// observabilityScope: self.observabilityScope, +// fileSystem: self.fileSystem +// ) +// } catch { +// return .failure(error) +// } +// // Check if we ended up with the host toolchain. +// if hostSwiftSDK == swiftSDK { +// return self._hostToolchain +// } +// +// return Result(catching: { +// try UserToolchain(swiftSDK: swiftSDK, environment: self.environment, fileSystem: self.fileSystem) +// }) +// }() + /// Lazily compute the host toolchain used to compile the package description. private lazy var _hostToolchain: Result = { return Result(catching: { diff --git a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift index 90d14f2c3c8..856a69f3950 100644 --- a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift @@ -527,8 +527,9 @@ public struct SwiftSDK: Equatable { ) throws -> SwiftSDK { try self.systemSwiftSDK( binDir, - originalWorkingDirectory: originalWorkingDirectory, - environment: environment + environment: environment, + observabilityScope: observabilityScope, + fileSystem: fileSystem ) } @@ -538,11 +539,11 @@ public struct SwiftSDK: Equatable { /// will result in the SDK for the corresponding Darwin platform. private static func systemSwiftSDK( _ binDir: AbsolutePath? = nil, - originalWorkingDirectory: AbsolutePath? = nil, - environment: [String: String] = ProcessEnv.vars, + environment: Environment = .current, + observabilityScope: ObservabilityScope? = nil, + fileSystem: any FileSystem = localFileSystem, darwinPlatformOverride: DarwinPlatform? = nil ) throws -> SwiftSDK { - let originalWorkingDirectory = originalWorkingDirectory ?? localFileSystem.currentWorkingDirectory // Select the correct binDir. if environment["SWIFTPM_CUSTOM_BINDIR"] != nil { print("SWIFTPM_CUSTOM_BINDIR was deprecated in favor of SWIFTPM_CUSTOM_BIN_DIR") @@ -559,7 +560,7 @@ public struct SwiftSDK: Equatable { sdkPath = try AbsolutePath(validating: value) } else { // No value in env, so search for it. - let sdkPathStr = try TSCBasic.Process.checkNonZeroExit( + let sdkPathStr = try AsyncProcess.checkNonZeroExit( arguments: ["/usr/bin/xcrun", "--sdk", darwinPlatform.xcrunName, "--show-sdk-path"], environment: environment ).spm_chomp() @@ -633,7 +634,7 @@ public struct SwiftSDK: Equatable { /// Returns ``SwiftSDK/PlatformPaths`` for the provided Darwin platform. public static func sdkPlatformPaths( for darwinPlatform: DarwinPlatform, - environment: EnvironmentVariables = .process() + environment: Environment = .current ) throws -> PlatformPaths { if let path = _sdkPlatformFrameworkPath[darwinPlatform] { return path @@ -675,7 +676,7 @@ public struct SwiftSDK: Equatable { public static func defaultSwiftSDK( for targetTriple: Triple, hostSDK: SwiftSDK, - environment: [String: String] = ProcessEnv.vars + environment: Environment = .current ) -> SwiftSDK? { if targetTriple.isWASI() { let wasiSysroot = hostSDK.toolset.rootPaths.first? @@ -738,12 +739,23 @@ public struct SwiftSDK: Equatable { } else { throw SwiftSDKError.noSwiftSDKDecoded(customDestination) } - } else if let triple = customCompileTriple, - let targetSwiftSDK = SwiftSDK.defaultSwiftSDK(for: triple, hostSDK: hostSwiftSDK) + } else if let targetTriple = customCompileTriple, + let targetSwiftSDK = SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) { swiftSDK = targetSwiftSDK } else if let swiftSDKSelector { - swiftSDK = try store.selectBundle(matching: swiftSDKSelector, hostTriple: hostTriple) + do { + swiftSDK = try store.selectBundle(matching: swiftSDKSelector, hostTriple: hostTriple) + } catch { + // If a user-installed bundle for the selector doesn't exist, check if the + // selector is recognized as a default SDK. + if let targetTriple = try? Triple(swiftSDKSelector), + let defaultSDK = SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) { + swiftSDK = defaultSDK + } else { + throw error + } + } } else { // Otherwise use the host toolchain. swiftSDK = hostSwiftSDK From 4633c7f37ba04f24c462cf008cc003d77ad02a80 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Tue, 27 Aug 2024 23:46:48 -0400 Subject: [PATCH 14/25] tweaks --- Sources/Commands/Utilities/TestingSupport.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index 63b3e48aee6..9d4ce944c46 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -112,7 +112,8 @@ enum TestingSupport { var args = [String]() #if os(macOS) let targetTriple = try swiftCommandState.getTargetToolchain().targetTriple - guard targetTriple.darwinPlatform == .macOS else { + let hostTriple = try swiftCommandState.getHostToolchain().targetTriple + guard hostTriple.isRuntimeCompatible(with: targetTriple) else { swiftCommandState.observabilityScope.emit(error: """ Attempting to run tests cross-compiled for non-macOS target '\(targetTriple)'; \ this is currently unsupported. From c610dc8a00565b97ac2e365dd3c8bbfd11e946a8 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Tue, 27 Aug 2024 23:47:18 -0400 Subject: [PATCH 15/25] remove commented code --- Sources/CoreCommands/SwiftCommandState.swift | 80 -------------------- 1 file changed, 80 deletions(-) diff --git a/Sources/CoreCommands/SwiftCommandState.swift b/Sources/CoreCommands/SwiftCommandState.swift index 44856589668..e281e1efa7a 100644 --- a/Sources/CoreCommands/SwiftCommandState.swift +++ b/Sources/CoreCommands/SwiftCommandState.swift @@ -905,86 +905,6 @@ public final class SwiftCommandState { }) }() -// private lazy var _targetToolchain: Result = { -// let swiftSDK: SwiftSDK -// let hostSwiftSDK: SwiftSDK -// let store = SwiftSDKBundleStore( -// swiftSDKsDirectory: self.sharedSwiftSDKsDirectory, -// fileSystem: fileSystem, -// observabilityScope: observabilityScope, -// outputHandler: { print($0.description) } -// ) -// do { -// let hostToolchain = try _hostToolchain.get() -// hostSwiftSDK = hostToolchain.swiftSDK -// -// if options.build.deprecatedSwiftSDKSelector != nil { -// self.observabilityScope.emit( -// warning: "`--experimental-swift-sdk` is deprecated and will be removed in a future version of SwiftPM. Use `--swift-sdk` instead." -// ) -// if swiftSDKs.count == 1 { -// swiftSDK = swiftSDKs[0] -// } else if swiftSDKs.count > 1, -// let triple = options.build.customCompileTriple, -// let matchingSDK = swiftSDKs.first(where: { $0.targetTriple == triple }) -// { -// swiftSDK = matchingSDK -// } else { -// return .failure(SwiftSDKError.noSwiftSDKDecoded(customDestination)) -// } -// } else if let targetTriple = options.build.customCompileTriple, -// let targetSwiftSDK = SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) -// { -// swiftSDK = targetSwiftSDK -// } else if let swiftSDKSelector = options.build.swiftSDKSelector { -// do { -// swiftSDK = try SwiftSDKBundle.selectBundle( -// fromBundlesAt: sharedSwiftSDKsDirectory, -// fileSystem: fileSystem, -// matching: swiftSDKSelector, -// hostTriple: hostTriple, -// observabilityScope: observabilityScope -// ) -// } catch { -// // If a user-installed bundle for the selector doesn't exist, check if the -// // selector is recognized as a default SDK. -// if let targetTriple = try? Triple(swiftSDKSelector), -// let defaultSDK = SwiftSDK.defaultSwiftSDK(for: targetTriple, hostSDK: hostSwiftSDK) { -// swiftSDK = defaultSDK -// } else { -// throw error -// } -// } -// } else { -// // Otherwise use the host toolchain. -// swiftSDK = hostSwiftSDK -// } -// swiftSDK = try SwiftSDK.deriveTargetSwiftSDK( -// hostSwiftSDK: hostSwiftSDK, -// hostTriple: hostToolchain.targetTriple, -// customCompileDestination: options.locations.customCompileDestination, -// customCompileTriple: options.build.customCompileTriple, -// customCompileToolchain: options.build.customCompileToolchain, -// customCompileSDK: options.build.customCompileSDK, -// swiftSDKSelector: options.build.swiftSDKSelector ?? options.build.deprecatedSwiftSDKSelector, -// architectures: options.build.architectures, -// store: store, -// observabilityScope: self.observabilityScope, -// fileSystem: self.fileSystem -// ) -// } catch { -// return .failure(error) -// } -// // Check if we ended up with the host toolchain. -// if hostSwiftSDK == swiftSDK { -// return self._hostToolchain -// } -// -// return Result(catching: { -// try UserToolchain(swiftSDK: swiftSDK, environment: self.environment, fileSystem: self.fileSystem) -// }) -// }() - /// Lazily compute the host toolchain used to compile the package description. private lazy var _hostToolchain: Result = { return Result(catching: { From 7e9d820b6a0c1187f0e22d9e1dba49762b451d18 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Wed, 28 Aug 2024 00:13:44 -0400 Subject: [PATCH 16/25] public --- Sources/PackageModel/SwiftSDKs/SwiftSDK.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift index 856a69f3950..389709e89d1 100644 --- a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift @@ -706,7 +706,6 @@ public struct SwiftSDK: Equatable { } /// Computes the target Swift SDK for the given options. - @_spi(SwiftPMInternal) public static func deriveTargetSwiftSDK( hostSwiftSDK: SwiftSDK, hostTriple: Triple, From 78bed58cfeed4e9cd893dbcc273d6e5a1004230a Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Wed, 28 Aug 2024 00:34:26 -0400 Subject: [PATCH 17/25] Add another test --- Tests/PackageModelTests/SwiftSDKBundleTests.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Tests/PackageModelTests/SwiftSDKBundleTests.swift b/Tests/PackageModelTests/SwiftSDKBundleTests.swift index ab9da497dd2..9fbd8d0c1fa 100644 --- a/Tests/PackageModelTests/SwiftSDKBundleTests.swift +++ b/Tests/PackageModelTests/SwiftSDKBundleTests.swift @@ -432,6 +432,19 @@ final class SwiftSDKBundleTests: XCTestCase { XCTAssertEqual(targetSwiftSDK.toolset.rootPaths, [toolsetRootPath] + hostSwiftSDK.toolset.rootPaths) } + do { + let targetSwiftSDK = try SwiftSDK.deriveTargetSwiftSDK( + hostSwiftSDK: hostSwiftSDK, + hostTriple: hostTriple, + swiftSDKSelector: "wasm32-unknown-wasi", + store: store, + observabilityScope: system.topScope, + fileSystem: fileSystem + ) + // Ensure that triples that have a `defaultSwiftSDK` are handled + XCTAssertEqual(targetSwiftSDK.targetTriple?.triple, "wasm32-unknown-wasi") + } + do { // Check explicit overriding options. let customCompileSDK = AbsolutePath("/path/to/sdk") From 0b09cb1baa2d1789ac6a853891cb3d918157712d Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Wed, 28 Aug 2024 01:02:46 -0400 Subject: [PATCH 18/25] Move SPI change into a separate PR --- Sources/PackageModel/SwiftSDKs/SwiftSDK.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift index 389709e89d1..856a69f3950 100644 --- a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift @@ -706,6 +706,7 @@ public struct SwiftSDK: Equatable { } /// Computes the target Swift SDK for the given options. + @_spi(SwiftPMInternal) public static func deriveTargetSwiftSDK( hostSwiftSDK: SwiftSDK, hostTriple: Triple, From b6870b3d7734427f6f9662be5f8d3c3a817421e0 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Fri, 30 Aug 2024 19:16:19 -0400 Subject: [PATCH 19/25] Support platform-specific SDKROOT --- Sources/PackageModel/SwiftSDKs/SwiftSDK.swift | 2 ++ Tests/PackageModelTests/SwiftSDKTests.swift | 13 +++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift index 389709e89d1..c331a5428af 100644 --- a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift @@ -558,6 +558,8 @@ public struct SwiftSDK: Equatable { // Get the SDK. if let value = environment["SDKROOT"] { sdkPath = try AbsolutePath(validating: value) + } else if let value = environment[EnvironmentKey("SDKROOT_\(darwinPlatform.xcrunName)")] { + sdkPath = try AbsolutePath(validating: value) } else { // No value in env, so search for it. let sdkPathStr = try AsyncProcess.checkNonZeroExit( diff --git a/Tests/PackageModelTests/SwiftSDKTests.swift b/Tests/PackageModelTests/SwiftSDKTests.swift index 360856441e9..90bd060acc3 100644 --- a/Tests/PackageModelTests/SwiftSDKTests.swift +++ b/Tests/PackageModelTests/SwiftSDKTests.swift @@ -621,15 +621,16 @@ final class DestinationTests: XCTestCase { let hostSDK = try SwiftSDK.hostSwiftSDK("/prefix/bin") #if os(macOS) + let iOSRoot = try AbsolutePath(validating: "/usr/share/iPhoneOS.sdk") let iOSTriple = try Triple("arm64-apple-ios") - let iOS = try XCTUnwrap(SwiftSDK.defaultSwiftSDK(for: iOSTriple, hostSDK: hostSDK)) + let iOS = try XCTUnwrap(SwiftSDK.defaultSwiftSDK( + for: iOSTriple, + hostSDK: hostSDK, + environment: ["SDKROOT_iphoneos": iOSRoot.pathString] + )) XCTAssertEqual(iOS.toolset.rootPaths, hostSDK.toolset.rootPaths) - let sdkPath = try XCTUnwrap(iOS.pathsConfiguration.sdkRootPath) - XCTAssertEqual(sdkPath.extension, "sdk") - - let sdkName = try XCTUnwrap(sdkPath.components.last) - XCTAssert(sdkName.hasPrefix("iPhoneOS")) + XCTAssertEqual(iOS.pathsConfiguration.sdkRootPath, iOSRoot) let cFlags = iOS.toolset.knownTools[.cCompiler]?.extraCLIOptions ?? [] XCTAssertFalse(cFlags.contains { $0.lowercased().contains("macos") }, "Found macOS path in \(cFlags)") From c2e9ccaaece9d1c50321744a372c3c9151e9d82d Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Fri, 30 Aug 2024 23:37:05 -0400 Subject: [PATCH 20/25] more env vars --- Sources/PackageModel/SwiftSDKs/SwiftSDK.swift | 6 ++++-- Tests/PackageModelTests/SwiftSDKTests.swift | 9 +++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift index c331a5428af..543e27dd667 100644 --- a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift @@ -558,7 +558,7 @@ public struct SwiftSDK: Equatable { // Get the SDK. if let value = environment["SDKROOT"] { sdkPath = try AbsolutePath(validating: value) - } else if let value = environment[EnvironmentKey("SDKROOT_\(darwinPlatform.xcrunName)")] { + } else if let value = environment[EnvironmentKey("SWIFTPM_SDKROOT_\(darwinPlatform.xcrunName)")] { sdkPath = try AbsolutePath(validating: value) } else { // No value in env, so search for it. @@ -641,7 +641,9 @@ public struct SwiftSDK: Equatable { if let path = _sdkPlatformFrameworkPath[darwinPlatform] { return path } - let platformPath = try AsyncProcess.checkNonZeroExit( + let platformPath = try environment[ + EnvironmentKey("SWIFTPM_PLATFORM_PATH_\(darwinPlatform.platformName)") + ] ?? AsyncProcess.checkNonZeroExit( arguments: ["/usr/bin/xcrun", "--sdk", darwinPlatform.platformName, "--show-sdk-platform-path"], environment: environment ).spm_chomp() diff --git a/Tests/PackageModelTests/SwiftSDKTests.swift b/Tests/PackageModelTests/SwiftSDKTests.swift index 90bd060acc3..2d11360b9ea 100644 --- a/Tests/PackageModelTests/SwiftSDKTests.swift +++ b/Tests/PackageModelTests/SwiftSDKTests.swift @@ -621,18 +621,23 @@ final class DestinationTests: XCTestCase { let hostSDK = try SwiftSDK.hostSwiftSDK("/prefix/bin") #if os(macOS) - let iOSRoot = try AbsolutePath(validating: "/usr/share/iPhoneOS.sdk") + let iOSPlatform = try AbsolutePath(validating: "/usr/share/iPhoneOS.platform") + let iOSRoot = try AbsolutePath(validating: "/usr/share/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk") let iOSTriple = try Triple("arm64-apple-ios") let iOS = try XCTUnwrap(SwiftSDK.defaultSwiftSDK( for: iOSTriple, hostSDK: hostSDK, - environment: ["SDKROOT_iphoneos": iOSRoot.pathString] + environment: [ + "SWIFTPM_PLATFORM_PATH_iphoneos": iOSPlatform.pathString, + "SWIFTPM_SDKROOT_iphoneos": iOSRoot.pathString, + ] )) XCTAssertEqual(iOS.toolset.rootPaths, hostSDK.toolset.rootPaths) XCTAssertEqual(iOS.pathsConfiguration.sdkRootPath, iOSRoot) let cFlags = iOS.toolset.knownTools[.cCompiler]?.extraCLIOptions ?? [] + XCTAssert(cFlags.contains(["-F", "\(iOSPlatform.pathString)/Developer/Library/Frameworks"])) XCTAssertFalse(cFlags.contains { $0.lowercased().contains("macos") }, "Found macOS path in \(cFlags)") #endif } From 5560fd3659b046e4443198e813ef19e0b77ff37a Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sun, 1 Sep 2024 21:04:16 -0400 Subject: [PATCH 21/25] potential fixes --- Sources/Commands/Utilities/TestingSupport.swift | 14 ++++---------- Sources/PackageModel/SwiftSDKs/SwiftSDK.swift | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index 9d4ce944c46..e769dc7f76d 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -134,13 +134,6 @@ enum TestingSupport { library: .xctest ) - // Add the sdk platform path if we have it. If this is not present, we might always end up failing. - // Since XCTestHelper targets macOS, we need the macOS platform paths here. - let sdkPlatformPaths = try SwiftSDK.sdkPlatformPaths(for: .macOS) - // appending since we prefer the user setting (if set) to the one we inject - env.appendPath(key: "DYLD_FRAMEWORK_PATH", value: sdkPlatformPaths.frameworks.pathString) - env.appendPath(key: "DYLD_LIBRARY_PATH", value: sdkPlatformPaths.libraries.pathString) - try AsyncProcess.checkNonZeroExit(arguments: args, environment: env) // Read the temporary file's content. return try swiftCommandState.fileSystem.readFileContents(AbsolutePath(tempFile.path)) @@ -203,10 +196,11 @@ enum TestingSupport { return env #else // Add the sdk platform path if we have it. - if let sdkPlatformFrameworksPath = try? SwiftSDK.sdkPlatformFrameworkPaths() { + // Since XCTestHelper targets macOS, we need the macOS platform paths here. + if let sdkPlatformPaths = try? SwiftSDK.sdkPlatformPaths(for: .macOS) { // appending since we prefer the user setting (if set) to the one we inject - env.appendPath(key: "DYLD_FRAMEWORK_PATH", value: sdkPlatformFrameworksPath.fwk.pathString) - env.appendPath(key: "DYLD_LIBRARY_PATH", value: sdkPlatformFrameworksPath.lib.pathString) + env.appendPath(key: "DYLD_FRAMEWORK_PATH", value: sdkPlatformPaths.frameworks.pathString) + env.appendPath(key: "DYLD_LIBRARY_PATH", value: sdkPlatformPaths.libraries.pathString) } // We aren't using XCTest's harness logic to run Swift Testing tests. diff --git a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift index 543e27dd667..31e290cd9ac 100644 --- a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift @@ -615,7 +615,7 @@ public struct SwiftSDK: Equatable { /// /// The referenced directories may contain, for example, test support utilities. /// - /// - SeeAlso: ``sdkPlatformFrameworkPaths(for:environment:)`` + /// - SeeAlso: ``sdkPlatformPaths(for:environment:)`` public struct PlatformPaths { /// Path to the directory containing auxiliary platform frameworks. public var frameworks: AbsolutePath From 79f582dfbaacdf002efa4ce90600dfe3bc3ca37c Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sun, 1 Sep 2024 21:08:30 -0400 Subject: [PATCH 22/25] fix warning --- Sources/Commands/Utilities/TestingSupport.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index e769dc7f76d..ee191ad4d1c 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -123,7 +123,7 @@ enum TestingSupport { let data: String = try withTemporaryFile { tempFile in args = [try Self.xctestHelperPath(swiftCommandState: swiftCommandState).pathString, path.pathString, tempFile.path.pathString] - var env = try Self.constructTestEnvironment( + let env = try Self.constructTestEnvironment( toolchain: try swiftCommandState.getTargetToolchain(), destinationBuildParameters: swiftCommandState.buildParametersForTest( enableCodeCoverage: enableCodeCoverage, From 3fe9ac7e521e3ad6025cf15696da0d406462f67c Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sun, 1 Sep 2024 21:17:22 -0400 Subject: [PATCH 23/25] drop xctest platform checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I’m not sure if this is causing CI to fail but we should probably add these checks somewhere else where they can apply to swift-testing too. Not in the critical path so worth moving to a followup. --- Sources/Commands/Utilities/TestingSupport.swift | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index ee191ad4d1c..63b55b616db 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -111,16 +111,6 @@ enum TestingSupport { // Run the correct tool. var args = [String]() #if os(macOS) - let targetTriple = try swiftCommandState.getTargetToolchain().targetTriple - let hostTriple = try swiftCommandState.getHostToolchain().targetTriple - guard hostTriple.isRuntimeCompatible(with: targetTriple) else { - swiftCommandState.observabilityScope.emit(error: """ - Attempting to run tests cross-compiled for non-macOS target '\(targetTriple)'; \ - this is currently unsupported. - """) - return [] - } - let data: String = try withTemporaryFile { tempFile in args = [try Self.xctestHelperPath(swiftCommandState: swiftCommandState).pathString, path.pathString, tempFile.path.pathString] let env = try Self.constructTestEnvironment( From 24cfc46a41a6c337dc4c29f8d44ca682089a9dce Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sun, 1 Sep 2024 21:22:13 -0400 Subject: [PATCH 24/25] use xcrunName for platformPath --- Sources/PackageModel/SwiftSDKs/SwiftSDK.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift index 31e290cd9ac..c6aaad770b7 100644 --- a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift @@ -644,7 +644,7 @@ public struct SwiftSDK: Equatable { let platformPath = try environment[ EnvironmentKey("SWIFTPM_PLATFORM_PATH_\(darwinPlatform.platformName)") ] ?? AsyncProcess.checkNonZeroExit( - arguments: ["/usr/bin/xcrun", "--sdk", darwinPlatform.platformName, "--show-sdk-platform-path"], + arguments: ["/usr/bin/xcrun", "--sdk", darwinPlatform.xcrunName, "--show-sdk-platform-path"], environment: environment ).spm_chomp() From 8351d149c3d46bcac4b4f28fdbd96f94a008db6f Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Wed, 4 Sep 2024 16:28:42 -0400 Subject: [PATCH 25/25] Use xcrunName for platform path override as well --- Sources/PackageModel/SwiftSDKs/SwiftSDK.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift index c6aaad770b7..c9cc039fb6c 100644 --- a/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift +++ b/Sources/PackageModel/SwiftSDKs/SwiftSDK.swift @@ -642,7 +642,7 @@ public struct SwiftSDK: Equatable { return path } let platformPath = try environment[ - EnvironmentKey("SWIFTPM_PLATFORM_PATH_\(darwinPlatform.platformName)") + EnvironmentKey("SWIFTPM_PLATFORM_PATH_\(darwinPlatform.xcrunName)") ] ?? AsyncProcess.checkNonZeroExit( arguments: ["/usr/bin/xcrun", "--sdk", darwinPlatform.xcrunName, "--show-sdk-platform-path"], environment: environment