From ee91bc21a372a45f08902f57e2008d0d4f6f9d2d Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 26 Jul 2024 18:12:35 -0700 Subject: [PATCH 1/6] [PackageModel] Always prefer a custom swift-testing location over SDK On MacOS toolchain can shadow SDK content. This method is intended to locate and include swift-testing library from a toolchain before sdk content which to sure that builds that use a custom toolchain always get a custom swift-testing library as well. --- Sources/PackageModel/Toolchain.swift | 14 ++++-- Sources/PackageModel/UserToolchain.swift | 54 +++++++++++++++++++++--- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/Sources/PackageModel/Toolchain.swift b/Sources/PackageModel/Toolchain.swift index e0d995043e5..17c5e4824c3 100644 --- a/Sources/PackageModel/Toolchain.swift +++ b/Sources/PackageModel/Toolchain.swift @@ -74,20 +74,24 @@ extension Toolchain { public var hostLibDir: AbsolutePath { get throws { - return try toolchainLibDir.appending(components: ["swift", "host"]) + try Self.toolchainLibDir(swiftCompilerPath: self.swiftCompilerPath).appending( + components: ["swift", "host"] + ) } } public var macosSwiftStdlib: AbsolutePath { get throws { - return try AbsolutePath(validating: "../../lib/swift/macosx", relativeTo: resolveSymlinks(swiftCompilerPath)) + try Self.toolchainLibDir(swiftCompilerPath: self.swiftCompilerPath).appending( + components: ["swift", "macosx"] + ) } } public var toolchainLibDir: AbsolutePath { get throws { // FIXME: Not sure if it's better to base this off of Swift compiler or our own binary. - return try AbsolutePath(validating: "../../lib", relativeTo: resolveSymlinks(swiftCompilerPath)) + try Self.toolchainLibDir(swiftCompilerPath: self.swiftCompilerPath) } } @@ -110,4 +114,8 @@ extension Toolchain { public var extraSwiftCFlags: [String] { extraFlags.swiftCompilerFlags } + + package static func toolchainLibDir(swiftCompilerPath: AbsolutePath) throws -> AbsolutePath { + try AbsolutePath(validating: "../../lib", relativeTo: resolveSymlinks(swiftCompilerPath)) + } } diff --git a/Sources/PackageModel/UserToolchain.swift b/Sources/PackageModel/UserToolchain.swift index 803f7c654ff..08d5a68cc76 100644 --- a/Sources/PackageModel/UserToolchain.swift +++ b/Sources/PackageModel/UserToolchain.swift @@ -403,6 +403,38 @@ public final class UserToolchain: Toolchain { } #endif + /// On MacOS toolchain can shadow SDK content. This method is intended + /// to locate and include swift-testing library from a toolchain before + /// sdk content which to sure that builds that use a custom toolchain + /// always get a custom swift-testing library as well. + static func deriveMacOSSpecificSwiftTestingFlags( + derivedSwiftCompiler: AbsolutePath, + fileSystem: any FileSystem + ) throws -> [String] { + let toolchainLibDir = try toolchainLibDir( + swiftCompilerPath: derivedSwiftCompiler + ) + + let testingLibDir = toolchainLibDir.appending( + components: ["swift", "macosx", "testing"] + ) + + let testingPluginsDir = toolchainLibDir.appending( + components: ["swift", "host", "plugins", "testing"] + ) + + guard fileSystem.exists(toolchainLibDir), fileSystem.exists(testingPluginsDir) else { + return [] + } + + return [ + "-I", testingLibDir.pathString, + "-L", testingLibDir.pathString, + "-plugin-path", testingPluginsDir.pathString, + "-Xlinker", "-rpath", "-Xlinker", testingLibDir.pathString, + ] + } + internal static func deriveSwiftCFlags( triple: Triple, swiftSDK: SwiftSDK, @@ -596,15 +628,25 @@ public final class UserToolchain: Toolchain { self.targetTriple = triple + var swiftCompilerFlags: [String] = [] + #if os(macOS) + swiftCompilerFlags += try Self.deriveMacOSSpecificSwiftTestingFlags( + derivedSwiftCompiler: swiftCompilers.compile, + fileSystem: fileSystem + ) + #endif + + swiftCompilerFlags += try Self.deriveSwiftCFlags( + triple: triple, + swiftSDK: swiftSDK, + environment: environment, + fileSystem: fileSystem + ) + self.extraFlags = BuildFlags( cCompilerFlags: swiftSDK.toolset.knownTools[.cCompiler]?.extraCLIOptions ?? [], cxxCompilerFlags: swiftSDK.toolset.knownTools[.cxxCompiler]?.extraCLIOptions ?? [], - swiftCompilerFlags: try Self.deriveSwiftCFlags( - triple: triple, - swiftSDK: swiftSDK, - environment: environment, - fileSystem: fileSystem - ), + swiftCompilerFlags: swiftCompilerFlags, linkerFlags: swiftSDK.toolset.knownTools[.linker]?.extraCLIOptions ?? [], xcbuildFlags: swiftSDK.toolset.knownTools[.xcbuild]?.extraCLIOptions ?? []) From 45f712403a2f84df4b4766bea6b4905b1b2e80c9 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Mon, 29 Jul 2024 14:33:27 -0700 Subject: [PATCH 2/6] [PackageModel] Support swift-testing in the toolchain on Windows The library is going to be installed into SDK beside XCTest. --- Sources/PackageModel/UserToolchain.swift | 40 +++++++++++++++---- .../PackageModel/WindowsToolchainInfo.swift | 5 +++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/Sources/PackageModel/UserToolchain.swift b/Sources/PackageModel/UserToolchain.swift index 08d5a68cc76..7ed36a9ce45 100644 --- a/Sources/PackageModel/UserToolchain.swift +++ b/Sources/PackageModel/UserToolchain.swift @@ -455,6 +455,7 @@ public final class UserToolchain: Toolchain { if let SDKROOT = environment["SDKROOT"], let sdkroot = try? AbsolutePath(validating: SDKROOT) { var runtime: [String] = [] var xctest: [String] = [] + var swiftTesting: [String] = [] var extraSwiftCFlags: [String] = [] if let settings = WindowsSDKSettings( @@ -476,7 +477,7 @@ public final class UserToolchain: Toolchain { // The layout of the SDK is as follows: // - // Library/Developer/Platforms/[PLATFORM].platform/Developer/Library/XCTest-[VERSION]/... + // Library/Developer/Platforms/[PLATFORM].platform/Developer/Library/-[VERSION]/... // Library/Developer/Platforms/[PLATFORM].platform/Developer/SDKs/[PLATFORM].sdk/... // // SDKROOT points to [PLATFORM].sdk @@ -487,14 +488,17 @@ public final class UserToolchain: Toolchain { observabilityScope: nil, filesystem: fileSystem ) { - let installation: AbsolutePath = + let XCTestInstallation: AbsolutePath = platform.appending("Developer") .appending("Library") .appending("XCTest-\(info.defaults.xctestVersion)") xctest = try [ "-I", - AbsolutePath(validating: "usr/lib/swift/windows", relativeTo: installation).pathString, + AbsolutePath( + validating: "usr/lib/swift/windows", + relativeTo: XCTestInstallation + ).pathString, // Migration Path // // Older Swift (<=5.7) installations placed the @@ -507,11 +511,13 @@ public final class UserToolchain: Toolchain { "-I", AbsolutePath( validating: "usr/lib/swift/windows/\(triple.archName)", - relativeTo: installation + relativeTo: XCTestInstallation ).pathString, "-L", - AbsolutePath(validating: "usr/lib/swift/windows/\(triple.archName)", relativeTo: installation) - .pathString, + AbsolutePath( + validating: "usr/lib/swift/windows/\(triple.archName)", + relativeTo: XCTestInstallation + ).pathString, ] // Migration Path @@ -524,16 +530,34 @@ public final class UserToolchain: Toolchain { // architecture subdirectory in `bin` if available. let implib = try AbsolutePath( validating: "usr/lib/swift/windows/XCTest.lib", - relativeTo: installation + relativeTo: XCTestInstallation ) if fileSystem.exists(implib) { xctest.append(contentsOf: ["-L", implib.parentDirectory.pathString]) } + let swiftTestingInstallation: AbsolutePath = + platform.appending("Developer") + .appending("Library") + .appending("Testing-\(info.defaults.swiftTestingVersion)") + + swiftTesting = try [ + "-I", + AbsolutePath( + validating: "usr/lib/swift/windows", + relativeTo: swiftTestingInstallation + ).pathString, + "-L", + AbsolutePath( + validating: "usr/lib/swift/windows/\(triple.archName)", + relativeTo: swiftTestingInstallation + ).pathString + ] + extraSwiftCFlags = info.defaults.extraSwiftCFlags ?? [] } - return ["-sdk", sdkroot.pathString] + runtime + xctest + extraSwiftCFlags + return ["-sdk", sdkroot.pathString] + runtime + xctest + swiftTesting + extraSwiftCFlags } } diff --git a/Sources/PackageModel/WindowsToolchainInfo.swift b/Sources/PackageModel/WindowsToolchainInfo.swift index 794ae3b4cab..3285f460436 100644 --- a/Sources/PackageModel/WindowsToolchainInfo.swift +++ b/Sources/PackageModel/WindowsToolchainInfo.swift @@ -78,6 +78,10 @@ public struct WindowsPlatformInfo { /// specifies the version string of the bundled XCTest. public let xctestVersion: String + /// SWIFT_TESTING_VERSION + /// specifies the version string of the bundled swift-testing. + public let swiftTestingVersion: String + /// SWIFTC_FLAGS /// Specifies extra flags to pass to swiftc from Swift Package Manager. public let extraSwiftCFlags: [String]? @@ -89,6 +93,7 @@ public struct WindowsPlatformInfo { extension WindowsPlatformInfo.DefaultProperties: Decodable { enum CodingKeys: String, CodingKey { case xctestVersion = "XCTEST_VERSION" + case swiftTestingVersion = "SWIFT_TESTING_VERSION" case extraSwiftCFlags = "SWIFTC_FLAGS" } } From 57830ef80bcffbd2ee4a143ad97e488dc81371ec Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Mon, 29 Jul 2024 15:42:31 -0700 Subject: [PATCH 3/6] [TestingSupport] Include SwiftTesting library in `PATH` on Windows Windows requires that the library with adjacent to the executable or we discoverable via PATH. --- .../Commands/Utilities/TestingSupport.swift | 7 +- .../PackageModel/ToolchainConfiguration.swift | 8 +- Sources/PackageModel/UserToolchain.swift | 127 ++++++++++++++---- 3 files changed, 116 insertions(+), 26 deletions(-) diff --git a/Sources/Commands/Utilities/TestingSupport.swift b/Sources/Commands/Utilities/TestingSupport.swift index 17723db964b..a99ec3985b7 100644 --- a/Sources/Commands/Utilities/TestingSupport.swift +++ b/Sources/Commands/Utilities/TestingSupport.swift @@ -176,8 +176,11 @@ enum TestingSupport { } #if !os(macOS) #if os(Windows) - if let location = toolchain.xctestPath { - env.prependPath(key: .path, value: location.pathString) + if let xctestLocation = toolchain.xctestPath { + env.prependPath(key: .path, value: xctestLocation.pathString) + } + if let swiftTestingLocation = toolchain.swiftTestingPathOnWindows { + env.prependPath(key: .path, value: swiftTestingLocation.pathString) } #endif return env diff --git a/Sources/PackageModel/ToolchainConfiguration.swift b/Sources/PackageModel/ToolchainConfiguration.swift index 7f9da9746c5..79d49a1aa04 100644 --- a/Sources/PackageModel/ToolchainConfiguration.swift +++ b/Sources/PackageModel/ToolchainConfiguration.swift @@ -42,6 +42,10 @@ public struct ToolchainConfiguration { /// This is optional for example on macOS w/o Xcode. public var xctestPath: AbsolutePath? + /// Path to the swift-testing utility. + /// Currently computed only for Windows. + public var swiftTestingPath: AbsolutePath? + /// Creates the set of manifest resources associated with a `swiftc` executable. /// /// - Parameters: @@ -59,7 +63,8 @@ public struct ToolchainConfiguration { swiftCompilerEnvironment: Environment = .current, swiftPMLibrariesLocation: SwiftPMLibrariesLocation? = nil, sdkRootPath: AbsolutePath? = nil, - xctestPath: AbsolutePath? = nil + xctestPath: AbsolutePath? = nil, + swiftTestingPath: AbsolutePath? = nil ) { let swiftPMLibrariesLocation = swiftPMLibrariesLocation ?? { return .init(swiftCompilerPath: swiftCompilerPath) @@ -72,6 +77,7 @@ public struct ToolchainConfiguration { self.swiftPMLibrariesLocation = swiftPMLibrariesLocation self.sdkRootPath = sdkRootPath self.xctestPath = xctestPath + self.swiftTestingPath = swiftTestingPath } } diff --git a/Sources/PackageModel/UserToolchain.swift b/Sources/PackageModel/UserToolchain.swift index 7ed36a9ce45..895660f5348 100644 --- a/Sources/PackageModel/UserToolchain.swift +++ b/Sources/PackageModel/UserToolchain.swift @@ -749,6 +749,19 @@ public final class UserToolchain: Toolchain { ) } + let swiftTestingPath: AbsolutePath? + if case .custom(_, let useXcrun) = searchStrategy, !useXcrun { + swiftTestingPath = nil + } else { + swiftTestingPath = try Self.deriveSwiftTestingPath( + swiftSDK: self.swiftSDK, + triple: triple, + environment: environment, + fileSystem: fileSystem + ) + } + + self.configuration = .init( librarianPath: librarianPath, swiftCompilerPath: swiftCompilers.manifest, @@ -756,7 +769,8 @@ public final class UserToolchain: Toolchain { swiftCompilerEnvironment: environment, swiftPMLibrariesLocation: swiftPMLibrariesLocation, sdkRootPath: self.swiftSDK.pathsConfiguration.sdkRootPath, - xctestPath: xctestPath + xctestPath: xctestPath, + swiftTestingPath: swiftTestingPath ) self.fileSystem = fileSystem @@ -852,6 +866,40 @@ public final class UserToolchain: Toolchain { return .none } + private static func getWindowsPlatformInfo( + swiftSDK: SwiftSDK, + environment: Environment, + fileSystem: any FileSystem + ) -> (AbsolutePath, WindowsPlatformInfo)? { + let sdkRoot: AbsolutePath + + if let sdkDir = swiftSDK.pathsConfiguration.sdkRootPath { + sdkRoot = sdkDir + } else if let SDKROOT = environment["SDKROOT"], let sdkDir = try? AbsolutePath(validating: SDKROOT) { + sdkRoot = sdkDir + } else { + return .none + } + + // The layout of the SDK is as follows: + // + // Library/Developer/Platforms/[PLATFORM].platform/Developer/Library/-[VERSION]/... + // Library/Developer/Platforms/[PLATFORM].platform/Developer/SDKs/[PLATFORM].sdk/... + // + // SDKROOT points to [PLATFORM].sdk + let platform = sdkRoot.parentDirectory.parentDirectory.parentDirectory + + guard let info = WindowsPlatformInfo( + reading: platform.appending("Info.plist"), + observabilityScope: nil, + filesystem: fileSystem + ) else { + return nil + } + + return (platform, info) + } + // TODO: We should have some general utility to find tools. private static func deriveXCTestPath( swiftSDK: SwiftSDK, @@ -868,28 +916,10 @@ public final class UserToolchain: Toolchain { return try AbsolutePath(validating: path) } } else if triple.isWindows() { - let sdkRoot: AbsolutePath - - if let sdkDir = swiftSDK.pathsConfiguration.sdkRootPath { - sdkRoot = sdkDir - } else if let SDKROOT = environment["SDKROOT"], let sdkDir = try? AbsolutePath(validating: SDKROOT) { - sdkRoot = sdkDir - } else { - return .none - } - - // The layout of the SDK is as follows: - // - // Library/Developer/Platforms/[PLATFORM].platform/Developer/Library/XCTest-[VERSION]/... - // Library/Developer/Platforms/[PLATFORM].platform/Developer/SDKs/[PLATFORM].sdk/... - // - // SDKROOT points to [PLATFORM].sdk - let platform = sdkRoot.parentDirectory.parentDirectory.parentDirectory - - if let info = WindowsPlatformInfo( - reading: platform.appending("Info.plist"), - observabilityScope: nil, - filesystem: fileSystem + if let (platform, info) = getWindowsPlatformInfo( + swiftSDK: swiftSDK, + environment: environment, + fileSystem: fileSystem ) { let xctest: AbsolutePath = platform.appending("Developer") @@ -952,6 +982,53 @@ public final class UserToolchain: Toolchain { return .none } + private static func deriveSwiftTestingPath( + swiftSDK: SwiftSDK, + triple: Triple, + environment: Environment, + fileSystem: any FileSystem + ) throws -> AbsolutePath? { + guard triple.isWindows() else { + return nil + } + + guard let (platform, info) = getWindowsPlatformInfo( + swiftSDK: swiftSDK, + environment: environment, + fileSystem: fileSystem + ) else { + return nil + } + + let swiftTesting: AbsolutePath = + platform.appending("Developer") + .appending("Library") + .appending("Testing-\(info.defaults.swiftTestingVersion)") + + let binPath: AbsolutePath? = switch triple.arch { + case .x86_64: // amd64 x86_64 x86_64h + swiftTesting.appending("usr") + .appending("bin64") + case .x86: // i386 i486 i586 i686 i786 i886 i986 + swiftTesting.appending("usr") + .appending("bin32") + case .arm: // armv7 and many more + swiftTesting.appending("usr") + .appending("bin32a") + case .aarch64: // aarch6 arm64 + swiftTesting.appending("usr") + .appending("bin64a") + default: + nil + } + + guard let path = binPath, fileSystem.exists(path) else { + return nil + } + + return path + } + public var sdkRootPath: AbsolutePath? { configuration.sdkRootPath } @@ -976,6 +1053,10 @@ public final class UserToolchain: Toolchain { configuration.xctestPath } + public var swiftTestingPathOnWindows: AbsolutePath? { + configuration.swiftTestingPath + } + private static func loadJSONResource( config: AbsolutePath, type: T.Type, `default`: T ) From 38c311167efa749db29046debcfd72cbdfb3044b Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Tue, 30 Jul 2024 14:14:50 -0700 Subject: [PATCH 4/6] [PackageModel] UserToolchain: Add -F when building with CommandLineTools --- Sources/PackageModel/UserToolchain.swift | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Sources/PackageModel/UserToolchain.swift b/Sources/PackageModel/UserToolchain.swift index 895660f5348..1482a75c295 100644 --- a/Sources/PackageModel/UserToolchain.swift +++ b/Sources/PackageModel/UserToolchain.swift @@ -410,10 +410,20 @@ public final class UserToolchain: Toolchain { static func deriveMacOSSpecificSwiftTestingFlags( derivedSwiftCompiler: AbsolutePath, fileSystem: any FileSystem - ) throws -> [String] { - let toolchainLibDir = try toolchainLibDir( + ) -> [String] { + // If this is CommandLineTools all we need to add is a frameworks path. + if let frameworksPath = try? AbsolutePath( + validating: "../../Library/Developer/Frameworks", + relativeTo: resolveSymlinks(derivedSwiftCompiler).parentDirectory + ), fileSystem.exists(frameworksPath.appending("Testing.framework")) { + return ["-F", frameworksPath.pathString] + } + + guard let toolchainLibDir = try? toolchainLibDir( swiftCompilerPath: derivedSwiftCompiler - ) + ) else { + return [] + } let testingLibDir = toolchainLibDir.appending( components: ["swift", "macosx", "testing"] @@ -654,7 +664,7 @@ public final class UserToolchain: Toolchain { var swiftCompilerFlags: [String] = [] #if os(macOS) - swiftCompilerFlags += try Self.deriveMacOSSpecificSwiftTestingFlags( + swiftCompilerFlags += Self.deriveMacOSSpecificSwiftTestingFlags( derivedSwiftCompiler: swiftCompilers.compile, fileSystem: fileSystem ) From 73b444112ae5fc2f1b3abe1e3ac3f174a590b4ca Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Fri, 2 Aug 2024 16:39:35 -0700 Subject: [PATCH 5/6] [PackageModel] Windows: Add a convenient way to get SDK root from environment Replace all of the copies of SDKROOT handling with a single property access on Environment type. --- Sources/PackageModel/UserToolchain.swift | 29 ++++++++++++++++-------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/Sources/PackageModel/UserToolchain.swift b/Sources/PackageModel/UserToolchain.swift index 1482a75c295..37efea6eb25 100644 --- a/Sources/PackageModel/UserToolchain.swift +++ b/Sources/PackageModel/UserToolchain.swift @@ -462,7 +462,7 @@ public final class UserToolchain: Toolchain { // Windows uses a variable named SDKROOT to determine the root of // the SDK. This is not the same value as the SDKROOT parameter // in Xcode, however, the value represents a similar concept. - if let SDKROOT = environment["SDKROOT"], let sdkroot = try? AbsolutePath(validating: SDKROOT) { + if let sdkroot = environment.windowsSDKRoot { var runtime: [String] = [] var xctest: [String] = [] var swiftTesting: [String] = [] @@ -703,7 +703,7 @@ public final class UserToolchain: Toolchain { } if triple.isWindows() { - if let SDKROOT = environment["SDKROOT"], let root = try? AbsolutePath(validating: SDKROOT) { + if let root = environment.windowsSDKRoot { if let settings = WindowsSDKSettings( reading: root.appending("SDKSettings.plist"), observabilityScope: nil, @@ -881,14 +881,16 @@ public final class UserToolchain: Toolchain { environment: Environment, fileSystem: any FileSystem ) -> (AbsolutePath, WindowsPlatformInfo)? { - let sdkRoot: AbsolutePath - - if let sdkDir = swiftSDK.pathsConfiguration.sdkRootPath { - sdkRoot = sdkDir - } else if let SDKROOT = environment["SDKROOT"], let sdkDir = try? AbsolutePath(validating: SDKROOT) { - sdkRoot = sdkDir + let sdkRoot: AbsolutePath? = if let sdkDir = swiftSDK.pathsConfiguration.sdkRootPath { + sdkDir + } else if let sdkDir = environment.windowsSDKRoot { + sdkDir } else { - return .none + nil + } + + guard let sdkRoot else { + return nil } // The layout of the SDK is as follows: @@ -1082,3 +1084,12 @@ public final class UserToolchain: Toolchain { return `default` } } + +extension Environment { + fileprivate var windowsSDKRoot: AbsolutePath? { + if let SDKROOT = self["SDKROOT"], let sdkDir = try? AbsolutePath(validating: SDKROOT) { + return sdkDir + } + return nil + } +} \ No newline at end of file From 5b2e5d25b7f98725316c23386251bef7941aaec4 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Sat, 3 Aug 2024 23:38:41 -0700 Subject: [PATCH 6/6] [PackageModel] Windows: Make swift-testing configuration optional This allows us to support older Windows toolchains with newer swift package manager even the project only uses XCTest. --- Sources/PackageModel/UserToolchain.swift | 42 +++++++++++-------- .../PackageModel/WindowsToolchainInfo.swift | 2 +- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/Sources/PackageModel/UserToolchain.swift b/Sources/PackageModel/UserToolchain.swift index 37efea6eb25..dd1a7c266c5 100644 --- a/Sources/PackageModel/UserToolchain.swift +++ b/Sources/PackageModel/UserToolchain.swift @@ -546,23 +546,25 @@ public final class UserToolchain: Toolchain { xctest.append(contentsOf: ["-L", implib.parentDirectory.pathString]) } - let swiftTestingInstallation: AbsolutePath = - platform.appending("Developer") - .appending("Library") - .appending("Testing-\(info.defaults.swiftTestingVersion)") - - swiftTesting = try [ - "-I", - AbsolutePath( - validating: "usr/lib/swift/windows", - relativeTo: swiftTestingInstallation - ).pathString, - "-L", - AbsolutePath( - validating: "usr/lib/swift/windows/\(triple.archName)", - relativeTo: swiftTestingInstallation - ).pathString - ] + if let swiftTestingVersion = info.defaults.swiftTestingVersion { + let swiftTestingInstallation: AbsolutePath = + platform.appending("Developer") + .appending("Library") + .appending("Testing-\(swiftTestingVersion)") + + swiftTesting = try [ + "-I", + AbsolutePath( + validating: "usr/lib/swift/windows", + relativeTo: swiftTestingInstallation + ).pathString, + "-L", + AbsolutePath( + validating: "usr/lib/swift/windows/\(triple.archName)", + relativeTo: swiftTestingInstallation + ).pathString + ] + } extraSwiftCFlags = info.defaults.extraSwiftCFlags ?? [] } @@ -1012,10 +1014,14 @@ public final class UserToolchain: Toolchain { return nil } + guard let swiftTestingVersion = info.defaults.swiftTestingVersion else { + return nil + } + let swiftTesting: AbsolutePath = platform.appending("Developer") .appending("Library") - .appending("Testing-\(info.defaults.swiftTestingVersion)") + .appending("Testing-\(swiftTestingVersion)") let binPath: AbsolutePath? = switch triple.arch { case .x86_64: // amd64 x86_64 x86_64h diff --git a/Sources/PackageModel/WindowsToolchainInfo.swift b/Sources/PackageModel/WindowsToolchainInfo.swift index 3285f460436..0e1bcbe8435 100644 --- a/Sources/PackageModel/WindowsToolchainInfo.swift +++ b/Sources/PackageModel/WindowsToolchainInfo.swift @@ -80,7 +80,7 @@ public struct WindowsPlatformInfo { /// SWIFT_TESTING_VERSION /// specifies the version string of the bundled swift-testing. - public let swiftTestingVersion: String + public let swiftTestingVersion: String? /// SWIFTC_FLAGS /// Specifies extra flags to pass to swiftc from Swift Package Manager.