diff --git a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift index 9edafd7bb9c..0bf30b71294 100644 --- a/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift @@ -130,7 +130,7 @@ public final class SwiftTargetBuildDescription { self.tempsPath.appending(component: self.target.c99name + ".swiftmodule.o") } - /// The path to the swifinterface file after compilation. + /// The path to the swiftinterface file after compilation. var parseableModuleInterfaceOutputPath: AbsolutePath { self.modulesPath.appending(component: self.target.c99name + ".swiftinterface") } diff --git a/Sources/Build/BuildPlan/BuildPlan+Product.swift b/Sources/Build/BuildPlan/BuildPlan+Product.swift index 2cbe8a8c46d..a0442686232 100644 --- a/Sources/Build/BuildPlan/BuildPlan+Product.swift +++ b/Sources/Build/BuildPlan/BuildPlan+Product.swift @@ -92,13 +92,13 @@ extension BuildPlan { buildProduct.staticTargets = dependencies.staticTargets buildProduct.dylibs = try dependencies.dylibs.map { - guard let product = productMap[$0.id] else { + guard let product = self.productMap[$0.id] else { throw InternalError("unknown product \($0)") } return product } buildProduct.objects += try dependencies.staticTargets.flatMap { targetName -> [AbsolutePath] in - guard let target = targetMap[targetName.id] else { + guard let target = self.targetMap[targetName.id] else { throw InternalError("unknown target \(targetName)") } return try target.objects diff --git a/Sources/PackageGraph/PackageGraph+Loading.swift b/Sources/PackageGraph/PackageGraph+Loading.swift index 7bd38f7ab78..2c456468f1d 100644 --- a/Sources/PackageGraph/PackageGraph+Loading.swift +++ b/Sources/PackageGraph/PackageGraph+Loading.swift @@ -280,7 +280,10 @@ private func createResolvedPackages( // Resolve module aliases, if specified, for targets and their dependencies // across packages. Aliasing will result in target renaming. - let moduleAliasingUsed = try resolveModuleAliases(packageBuilders: packageBuilders, observabilityScope: observabilityScope) + let moduleAliasingUsed = try resolveModuleAliases( + packageBuilders: packageBuilders, + observabilityScope: observabilityScope + ) // Scan and validate the dependencies for packageBuilder in packageBuilders { diff --git a/Sources/PackageGraph/PackageGraph.swift b/Sources/PackageGraph/PackageGraph.swift index 6ca5fc68b59..8a5e8c7426d 100644 --- a/Sources/PackageGraph/PackageGraph.swift +++ b/Sources/PackageGraph/PackageGraph.swift @@ -79,10 +79,14 @@ public struct PackageGraph { /// Returns true if a given target is present in root packages and is not excluded for the given build environment. public func isInRootPackages(_ target: ResolvedTarget, satisfying buildEnvironment: BuildEnvironment) -> Bool { // FIXME: This can be easily cached. - return rootPackages.reduce(into: IdentifiableSet()) { (accumulator: inout IdentifiableSet, package: ResolvedPackage) in + return rootPackages.reduce( + into: IdentifiableSet() + ) { (accumulator: inout IdentifiableSet, package: ResolvedPackage) in let allDependencies = package.targets.flatMap { $0.dependencies } let unsatisfiedDependencies = allDependencies.filter { !$0.satisfies(buildEnvironment) } - let unsatisfiedDependencyTargets = unsatisfiedDependencies.compactMap { (dep: ResolvedTarget.Dependency) -> ResolvedTarget? in + let unsatisfiedDependencyTargets = unsatisfiedDependencies.compactMap { ( + dep: ResolvedTarget.Dependency + ) -> ResolvedTarget? in switch dep { case .target(let target, _): return target @@ -152,7 +156,7 @@ public struct PackageGraph { for package in self.packages { let targetsToInclude: [ResolvedTarget] if rootPackages.contains(id: package.id) { - targetsToInclude = package.targets + targetsToInclude = Array(package.targets) } else { // Don't include tests targets from non-root packages so swift-test doesn't // try to run them. diff --git a/Sources/PackageGraph/Resolution/ResolvedPackage.swift b/Sources/PackageGraph/Resolution/ResolvedPackage.swift index bf8d81eac78..e745696036a 100644 --- a/Sources/PackageGraph/Resolution/ResolvedPackage.swift +++ b/Sources/PackageGraph/Resolution/ResolvedPackage.swift @@ -11,6 +11,9 @@ //===----------------------------------------------------------------------===// import Basics + +import struct OrderedCollections.OrderedDictionary + import PackageModel /// A fully resolved package. Contains resolved targets, products and dependencies of the package. @@ -64,8 +67,43 @@ public struct ResolvedPackage { platformVersionProvider: PlatformVersionProvider ) { self.underlying = underlying - self.targets = targets - self.products = products + + var processedTargets = OrderedDictionary( + uniqueKeysWithValues: targets.map { ($0.id, $0) } + ) + var processedProducts = [ResolvedProduct]() + // Make sure that direct macro dependencies of test products are also built for the target triple. + // Without this workaround, `assertMacroExpansion` in tests can't be built, as it requires macros + // and SwiftSyntax to be built for the target triple: https://github.com/apple/swift-package-manager/pull/7349 + for var product in products { + if product.type == .test { + var targets = IdentifiableSet() + for var target in product.targets { + var dependencies = [ResolvedTarget.Dependency]() + for dependency in target.dependencies { + switch dependency { + case .target(var target, let conditions) where target.type == .macro: + target.buildTriple = .destination + dependencies.append(.target(target, conditions: conditions)) + processedTargets[target.id] = target + case .product(var product, let conditions) where product.type == .macro: + product.buildTriple = .destination + dependencies.append(.product(product, conditions: conditions)) + default: + dependencies.append(dependency) + } + } + target.dependencies = dependencies + targets.insert(target) + } + product.targets = targets + } + + processedProducts.append(product) + } + + self.products = processedProducts + self.targets = Array(processedTargets.values) self.dependencies = dependencies self.defaultLocalization = defaultLocalization self.supportedPlatforms = supportedPlatforms diff --git a/Sources/PackageGraph/Resolution/ResolvedProduct.swift b/Sources/PackageGraph/Resolution/ResolvedProduct.swift index b2d23135c2f..c63e86bfabe 100644 --- a/Sources/PackageGraph/Resolution/ResolvedProduct.swift +++ b/Sources/PackageGraph/Resolution/ResolvedProduct.swift @@ -30,7 +30,7 @@ public struct ResolvedProduct { public let underlying: Product /// The top level targets contained in this product. - public private(set) var targets: IdentifiableSet + public internal(set) var targets: IdentifiableSet /// Executable target for test entry point file. public let testEntryPointTarget: ResolvedTarget? diff --git a/Sources/PackageGraph/Resolution/ResolvedTarget.swift b/Sources/PackageGraph/Resolution/ResolvedTarget.swift index 674df077510..69864b21e22 100644 --- a/Sources/PackageGraph/Resolution/ResolvedTarget.swift +++ b/Sources/PackageGraph/Resolution/ResolvedTarget.swift @@ -133,7 +133,7 @@ public struct ResolvedTarget { public let underlying: Target /// The dependencies of this target. - public private(set) var dependencies: [Dependency] + public internal(set) var dependencies: [Dependency] /// The default localization for resources. public let defaultLocalization: String? diff --git a/Tests/BuildTests/CrossCompilationBuildTests.swift b/Tests/BuildTests/CrossCompilationBuildTests.swift index 5026abbc443..f8a9ad600c0 100644 --- a/Tests/BuildTests/CrossCompilationBuildTests.swift +++ b/Tests/BuildTests/CrossCompilationBuildTests.swift @@ -70,12 +70,17 @@ final class CrossCompilationBuildPlanTests: XCTestCase { let macroProduct = try XCTUnwrap(macroProducts.first) XCTAssertEqual(macroProduct.buildParameters.triple, toolsTriple) - // FIXME: check for *toolsTriple* + // FIXME: check for *toolsTriple* let mmioTarget = try XCTUnwrap(plan.targets.first { try $0.swiftTarget().target.name == "MMIO" }?.swiftTarget()) - let compileArguments = try mmioTarget.compileArguments() + let compileArguments = try mmioTarget.emitCommandLine() XCTAssertMatch( compileArguments, - ["-Xfrontend", "-load-plugin-executable", "-Xfrontend", .contains(toolsTriple.tripleString)] + [ + "-I", .equal(mmioTarget.moduleOutputPath.parentDirectory.pathString), + .anySequence, + "-Xfrontend", "-load-plugin-executable", + "-Xfrontend", .contains(toolsTriple.tripleString) + ] ) } }