From 20a0846a6f3fbda86007b2ace0c28eef3931d475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boris=20B=C3=BCgling?= Date: Tue, 10 Oct 2023 20:19:11 -0700 Subject: [PATCH] Handle macOS CLT `--show-sdk-platform-path` issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have been seeing this issue for a while when using SwiftPM from the CommandLineTools package: ``` ❯ /usr/bin/xcrun --sdk macosx --show-sdk-platform-path xcrun: error: unable to lookup item 'PlatformPath' from command line tools installation xcrun: error: unable to lookup item 'PlatformPath' in SDK '/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk' ``` This changes SwiftPM to handle this gracefully during builds (a warning gets emitted) and to fail properly when running `swift test`. rdar://107479428 (cherry picked from commit 3ab568e1a27ec01c4515caf9475e4460d4f8c15b) --- Sources/Commands/SwiftTestTool.swift | 3 ++- Sources/CoreCommands/SwiftTool.swift | 2 +- Sources/PackageModel/Destination.swift | 32 +++++++++++++++++++------- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/Sources/Commands/SwiftTestTool.swift b/Sources/Commands/SwiftTestTool.swift index 42cd13745c1..0aa65cfd4b1 100644 --- a/Sources/Commands/SwiftTestTool.swift +++ b/Sources/Commands/SwiftTestTool.swift @@ -166,7 +166,8 @@ public struct SwiftTestTool: SwiftCommand { // validate XCTest available on darwin based systems let toolchain = try swiftTool.getDestinationToolchain() - if toolchain.triple.isDarwin() && toolchain.xctestPath == nil { + let isHostTestingAvailable = try swiftTool.getHostToolchain().destination.supportsTesting + if toolchain.triple.isDarwin() && toolchain.xctestPath == nil || !isHostTestingAvailable { throw TestError.xctestNotAvailable } } catch { diff --git a/Sources/CoreCommands/SwiftTool.swift b/Sources/CoreCommands/SwiftTool.swift index 669ef2dce14..14c41c865f5 100644 --- a/Sources/CoreCommands/SwiftTool.swift +++ b/Sources/CoreCommands/SwiftTool.swift @@ -792,7 +792,7 @@ public final class SwiftTool { private lazy var _hostToolchain: Result = { return Result(catching: { try UserToolchain(destination: Destination.hostDestination( - originalWorkingDirectory: self.originalWorkingDirectory)) + originalWorkingDirectory: self.originalWorkingDirectory, observabilityScope: self.observabilityScope)) }) }() diff --git a/Sources/PackageModel/Destination.swift b/Sources/PackageModel/Destination.swift index fa4902e23da..dc31709fdc3 100644 --- a/Sources/PackageModel/Destination.swift +++ b/Sources/PackageModel/Destination.swift @@ -132,6 +132,9 @@ public struct Destination: Equatable { /// The architectures to build for. We build for host architecture if this is empty. public var architectures: [String]? = nil + /// Whether or not the receiver supports testing. + public let supportsTesting: Bool + /// Root directory path of the SDK used to compile for the destination. @available(*, deprecated, message: "use `sdkRootDir` instead") public var sdk: AbsolutePath? { @@ -402,12 +405,14 @@ public struct Destination: Equatable { hostTriple: Triple? = nil, targetTriple: Triple? = nil, toolset: Toolset, - pathsConfiguration: PathsConfiguration + pathsConfiguration: PathsConfiguration, + supportsTesting: Bool = true ) { self.hostTriple = hostTriple self.targetTriple = targetTriple self.toolset = toolset self.pathsConfiguration = pathsConfiguration + self.supportsTesting = supportsTesting } /// Returns the bin directory for the host. @@ -428,7 +433,8 @@ public struct Destination: Equatable { public static func hostDestination( _ binDir: AbsolutePath? = nil, originalWorkingDirectory: AbsolutePath? = nil, - environment: [String: String] = ProcessEnv.vars + environment: [String: String] = ProcessEnv.vars, + observabilityScope: ObservabilityScope? = nil ) throws -> Destination { let originalWorkingDirectory = originalWorkingDirectory ?? localFileSystem.currentWorkingDirectory // Select the correct binDir. @@ -463,14 +469,23 @@ public struct Destination: Equatable { #endif // Compute common arguments for clang and swift. + let supportsTesting: Bool var extraCCFlags: [String] = [] var extraSwiftCFlags: [String] = [] #if os(macOS) - let sdkPaths = try Destination.sdkPlatformFrameworkPaths(environment: environment) - extraCCFlags += ["-F", sdkPaths.fwk.pathString] - extraSwiftCFlags += ["-F", sdkPaths.fwk.pathString] - extraSwiftCFlags += ["-I", sdkPaths.lib.pathString] - extraSwiftCFlags += ["-L", sdkPaths.lib.pathString] + do { + let sdkPaths = try Destination.sdkPlatformFrameworkPaths(environment: environment) + extraCCFlags += ["-F", sdkPaths.fwk.pathString] + extraSwiftCFlags += ["-F", sdkPaths.fwk.pathString] + extraSwiftCFlags += ["-I", sdkPaths.lib.pathString] + extraSwiftCFlags += ["-L", sdkPaths.lib.pathString] + supportsTesting = true + } catch { + supportsTesting = false + observabilityScope?.emit(warning: "could not determine XCTest paths: \(error)") + } + #else + supportsTesting = true #endif #if !os(Windows) @@ -485,7 +500,8 @@ public struct Destination: Equatable { ], rootPaths: [binDir] ), - pathsConfiguration: .init(sdkRootPath: sdkPath) + pathsConfiguration: .init(sdkRootPath: sdkPath), + supportsTesting: supportsTesting ) }