From 63bbdeeee1e06971bbaab36c0c8daab137be8d1a Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Mon, 25 Mar 2024 13:42:25 -0700 Subject: [PATCH 1/5] Give clang target description access to the package it's associated with We need this information to set `-w` and other package specific options. (cherry picked from commit c86ea6934edb171fd6900d22151f778b1bbdb2ab) From ad481a68e6afbbdb2ed8b541c53b3a5a1c3a1c22 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Mon, 25 Mar 2024 16:19:39 -0700 Subject: [PATCH 2/5] Add a workaround for swift-corelibs-foundation on Linux/Android CoreFoundation depends on dispatch, this dependency is implicit and dispatch itself is bundled with swift toolchains. Let's add a package specific workaround for Linux/Android targets to add toolchain resources directory to search paths of clang build targets. (cherry picked from commit 0871a0418205814f936dda3d2c2ab931c15dfff0) # Conflicts: # Sources/Build/BuildDescription/ClangTargetBuildDescription.swift --- .../ClangTargetBuildDescription.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift b/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift index e821ffa2331..7f9d1cf4f61 100644 --- a/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/ClangTargetBuildDescription.swift @@ -311,6 +311,18 @@ public final class ClangTargetBuildDescription { args += ["-I", includeSearchPath.pathString] } + // FIXME: Remove this once it becomes possible to express this dependency in a package manifest. + // + // On Linux/Android swift-corelibs-foundation depends on dispatch library which is + // currently shipped with the Swift toolchain. + if (triple.isLinux() || triple.isAndroid()) && self.package.id == .plain("swift-corelibs-foundation") { + let swiftCompilerPath = self.buildParameters.toolchain.swiftCompilerPath + let toolchainResourcesPath = swiftCompilerPath.parentDirectory + .parentDirectory + .appending(components: ["lib", "swift"]) + args += ["-I", toolchainResourcesPath.pathString] + } + // suppress warnings if the package is remote if self.package.isRemote { args += ["-w"] From 160d2eeb750c53074a42a28c8cb4054c590d9e0e Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Tue, 26 Mar 2024 10:21:38 -0700 Subject: [PATCH 3/5] NFC: Add a test-case for swift-corelibs-foundation workaround (cherry picked from commit d6cfaebd823c941505686739c336842cc1259cbf) # Conflicts: # Tests/BuildTests/ClangTargetBuildDescriptionTests.swift --- .../ClangTargetBuildDescriptionTests.swift | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift b/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift index 7b8a01802d2..f494f930559 100644 --- a/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift +++ b/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift @@ -30,6 +30,30 @@ final class ClangTargetBuildDescriptionTests: XCTestCase { XCTAssertTrue(try targetDescription.basicArguments().contains("-w")) } + func testSwiftCorelibsFoundationIncludeWorkaround() throws { + let macosParameters = mockBuildParameters( + toolchain: try UserToolchain.default, + targetTriple: .macOS) + let linuxParameters = mockBuildParameters( + toolchain: try UserToolchain.default, + targetTriple: .arm64Linux) + let androidParameters = mockBuildParameters( + toolchain: try UserToolchain.default, + targetTriple: .arm64Android) + + let macDescription = try makeTargetBuildDescription("swift-corelibs-foundation", + buildParameters: macosParameters) + XCTAssertFalse(try macDescription.basicArguments().contains("\(macosParameters.toolchain.swiftResourcesPath!)")) + + let linuxDescription = try makeTargetBuildDescription("swift-corelibs-foundation", + buildParameters: linuxParameters) + XCTAssertTrue(try linuxDescription.basicArguments().contains("\(linuxParameters.toolchain.swiftResourcesPath!)")) + + let androidDescription = try makeTargetBuildDescription("swift-corelibs-foundation", + buildParameters: androidParameters) + XCTAssertTrue(try androidDescription.basicArguments().contains("\(androidParameters.toolchain.swiftResourcesPath!)")) + } + private func makeClangTarget() throws -> ClangTarget { try ClangTarget( name: "dummy", From 604a25197962f542555029a2ad0646065683b989 Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Tue, 26 Mar 2024 10:46:18 -0700 Subject: [PATCH 4/5] NFC: Use mock toolchain for swift-corelib-foundation workaround testing (cherry picked from commit a85039c260cd4b2b990637b9ae9d7b1126878f62) # Conflicts: # Sources/SPMTestSupport/MockBuildTestHelper.swift --- .../SPMTestSupport/MockBuildTestHelper.swift | 22 ++++++++++--------- .../ClangTargetBuildDescriptionTests.swift | 15 +++++-------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/Sources/SPMTestSupport/MockBuildTestHelper.swift b/Sources/SPMTestSupport/MockBuildTestHelper.swift index 83662600628..cd49e7eef82 100644 --- a/Sources/SPMTestSupport/MockBuildTestHelper.swift +++ b/Sources/SPMTestSupport/MockBuildTestHelper.swift @@ -28,15 +28,15 @@ public struct MockToolchain: PackageModel.Toolchain { #else public let librarianPath = AbsolutePath("/fake/path/to/llvm-ar") #endif - public let swiftCompilerPath = AbsolutePath("/fake/path/to/swiftc") - public let includeSearchPaths = [AbsolutePath]() - public let librarySearchPaths = [AbsolutePath]() - public let swiftResourcesPath: AbsolutePath? = nil - public let swiftStaticResourcesPath: AbsolutePath? = nil - public let sdkRootPath: AbsolutePath? = nil - public let extraFlags = PackageModel.BuildFlags() - public let installedSwiftPMConfiguration = InstalledSwiftPMConfiguration.default - public let providedLibraries = [LibraryMetadata]() + package let swiftCompilerPath = AbsolutePath("/fake/path/to/swiftc") + package let includeSearchPaths = [AbsolutePath]() + package let librarySearchPaths = [AbsolutePath]() + package let swiftResourcesPath: AbsolutePath? + package let swiftStaticResourcesPath: AbsolutePath? = nil + package let sdkRootPath: AbsolutePath? = nil + package let extraFlags = PackageModel.BuildFlags() + package let installedSwiftPMConfiguration = InstalledSwiftPMConfiguration.default + package let providedLibraries = [LibraryMetadata]() public func getClangCompiler() throws -> AbsolutePath { "/fake/path/to/clang" @@ -50,7 +50,9 @@ public struct MockToolchain: PackageModel.Toolchain { #endif } - public init() {} + package init(swiftResourcesPath: AbsolutePath? = nil) { + self.swiftResourcesPath = swiftResourcesPath + } } extension Basics.Triple { diff --git a/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift b/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift index f494f930559..eabfee6ad10 100644 --- a/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift +++ b/Tests/BuildTests/ClangTargetBuildDescriptionTests.swift @@ -31,15 +31,11 @@ final class ClangTargetBuildDescriptionTests: XCTestCase { } func testSwiftCorelibsFoundationIncludeWorkaround() throws { - let macosParameters = mockBuildParameters( - toolchain: try UserToolchain.default, - targetTriple: .macOS) - let linuxParameters = mockBuildParameters( - toolchain: try UserToolchain.default, - targetTriple: .arm64Linux) - let androidParameters = mockBuildParameters( - toolchain: try UserToolchain.default, - targetTriple: .arm64Android) + let toolchain = MockToolchain(swiftResourcesPath: AbsolutePath("/fake/path/lib/swift")) + + let macosParameters = mockBuildParameters(toolchain: toolchain, targetTriple: .macOS) + let linuxParameters = mockBuildParameters(toolchain: toolchain, targetTriple: .arm64Linux) + let androidParameters = mockBuildParameters(toolchain: toolchain, targetTriple: .arm64Android) let macDescription = try makeTargetBuildDescription("swift-corelibs-foundation", buildParameters: macosParameters) @@ -47,6 +43,7 @@ final class ClangTargetBuildDescriptionTests: XCTestCase { let linuxDescription = try makeTargetBuildDescription("swift-corelibs-foundation", buildParameters: linuxParameters) + print(try linuxDescription.basicArguments()) XCTAssertTrue(try linuxDescription.basicArguments().contains("\(linuxParameters.toolchain.swiftResourcesPath!)")) let androidDescription = try makeTargetBuildDescription("swift-corelibs-foundation", From b8ccee6d3f929d891ffb7a4c6f29f1cf3a2066c1 Mon Sep 17 00:00:00 2001 From: Max Desiatov Date: Thu, 6 Jun 2024 16:14:25 +0100 Subject: [PATCH 5/5] Fix `package`/`public` mismatch --- Sources/SPMTestSupport/MockBuildTestHelper.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/SPMTestSupport/MockBuildTestHelper.swift b/Sources/SPMTestSupport/MockBuildTestHelper.swift index cd49e7eef82..28b4cf55c4b 100644 --- a/Sources/SPMTestSupport/MockBuildTestHelper.swift +++ b/Sources/SPMTestSupport/MockBuildTestHelper.swift @@ -20,7 +20,7 @@ import SPMBuildCore import TSCUtility import XCTest -public struct MockToolchain: PackageModel.Toolchain { +package struct MockToolchain: PackageModel.Toolchain { #if os(Windows) public let librarianPath = AbsolutePath("/fake/path/to/link.exe") #elseif os(iOS) || os(macOS) || os(tvOS) || os(watchOS) @@ -72,7 +72,7 @@ public let defaultTargetTriple: String = hostTriple.tripleString(forPlatformVers public let defaultTargetTriple: String = hostTriple.tripleString #endif -public func mockBuildParameters( +package func mockBuildParameters( buildPath: AbsolutePath = "/path/to/build", config: BuildConfiguration = .debug, toolchain: PackageModel.Toolchain = MockToolchain(),