Skip to content

Commit 6965245

Browse files
authored
Avoid building targets that are conditional on platform when building all (#8568)
When using the swiftbuild build system, and building all targets with a project that contains a target that is depended on only when on a specific platform that target should be skipped. Make the All(Excluding|Including)Tests generated targets depend only on targets that are reachable from the roots through dependencies that are either unconditional or are conditioned on the current platform.
1 parent f808b9f commit 6965245

File tree

3 files changed

+32
-8
lines changed

3 files changed

+32
-8
lines changed

Sources/SwiftBuildSupport/PIFBuilder.swift

+19-7
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ public final class PIFBuilder {
100100
func generatePIF(
101101
prettyPrint: Bool = true,
102102
preservePIFModelStructure: Bool = false,
103-
printPIFManifestGraphviz: Bool = false
103+
printPIFManifestGraphviz: Bool = false,
104+
buildParameters: BuildParameters
104105
) throws -> String {
105106
#if canImport(SwiftBuild)
106107
let encoder = prettyPrint ? JSONEncoder.makeWithDefaults() : JSONEncoder()
@@ -109,7 +110,7 @@ public final class PIFBuilder {
109110
encoder.userInfo[.encodeForSwiftBuild] = true
110111
}
111112

112-
let topLevelObject = try self.construct()
113+
let topLevelObject = try self.construct(buildParameters: buildParameters)
113114

114115
// Sign the PIF objects before encoding it for Swift Build.
115116
try PIF.sign(workspace: topLevelObject.workspace)
@@ -138,7 +139,7 @@ public final class PIFBuilder {
138139
private var cachedPIF: PIF.TopLevelObject?
139140

140141
/// Constructs a `PIF.TopLevelObject` representing the package graph.
141-
private func construct() throws -> PIF.TopLevelObject {
142+
private func construct(buildParameters: BuildParameters) throws -> PIF.TopLevelObject {
142143
try memoize(to: &self.cachedPIF) {
143144
guard let rootPackage = self.graph.rootPackages.only else {
144145
if self.graph.rootPackages.isEmpty {
@@ -174,7 +175,9 @@ public final class PIFBuilder {
174175
projects.append(
175176
try buildAggregateProject(
176177
packagesAndProjects: packagesAndProjects,
177-
observabilityScope: observabilityScope
178+
observabilityScope: observabilityScope,
179+
modulesGraph: graph,
180+
buildParameters: buildParameters
178181
)
179182
)
180183

@@ -197,7 +200,7 @@ public final class PIFBuilder {
197200
packageGraph: ModulesGraph,
198201
fileSystem: FileSystem,
199202
observabilityScope: ObservabilityScope,
200-
preservePIFModelStructure: Bool
203+
preservePIFModelStructure: Bool,
201204
) throws -> String {
202205
let parameters = PIFBuilderParameters(buildParameters, supportedSwiftVersions: [])
203206
let builder = Self(
@@ -206,7 +209,7 @@ public final class PIFBuilder {
206209
fileSystem: fileSystem,
207210
observabilityScope: observabilityScope
208211
)
209-
return try builder.generatePIF(preservePIFModelStructure: preservePIFModelStructure)
212+
return try builder.generatePIF(preservePIFModelStructure: preservePIFModelStructure, buildParameters: buildParameters)
210213
}
211214
}
212215

@@ -306,7 +309,9 @@ fileprivate final class PackagePIFBuilderDelegate: PackagePIFBuilder.BuildDelega
306309

307310
fileprivate func buildAggregateProject(
308311
packagesAndProjects: [(package: ResolvedPackage, project: ProjectModel.Project)],
309-
observabilityScope: ObservabilityScope
312+
observabilityScope: ObservabilityScope,
313+
modulesGraph: ModulesGraph,
314+
buildParameters: BuildParameters
310315
) throws -> ProjectModel.Project {
311316
precondition(!packagesAndProjects.isEmpty)
312317

@@ -367,6 +372,13 @@ fileprivate func buildAggregateProject(
367372
// conflicts with those from "PACKAGE-TARGET:Foo-dynamic".
368373
continue
369374
}
375+
376+
if let resolvedModule = modulesGraph.module(for: target.name) {
377+
guard modulesGraph.isInRootPackages(resolvedModule, satisfying: buildParameters.buildEnvironment) else {
378+
// Disconnected target, possibly due to platform when condition that isn't satisfied
379+
continue
380+
}
381+
}
370382

371383
aggregateProject[keyPath: allIncludingTestsTargetKeyPath].common.addDependency(
372384
on: target.id,

Sources/SwiftBuildSupport/SwiftBuildSystem.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,8 @@ public final class SwiftBuildSystem: SPMBuildCore.BuildSystem {
239239

240240
let pifBuilder = try await getPIFBuilder()
241241
let pif = try pifBuilder.generatePIF(
242-
printPIFManifestGraphviz: buildParameters.printPIFManifestGraphviz
242+
printPIFManifestGraphviz: buildParameters.printPIFManifestGraphviz,
243+
buildParameters: buildParameters
243244
)
244245

245246
try self.fileSystem.writeIfChanged(path: buildParameters.pifManifest, string: pif)

Tests/FunctionalTests/MiscellaneousTests.swift

+11
Original file line numberDiff line numberDiff line change
@@ -665,4 +665,15 @@ final class MiscellaneousTestCase: XCTestCase {
665665
XCTAssertEqual(errors, [], "unexpected errors: \(errors)")
666666
}
667667
}
668+
669+
func testRootPackageWithConditionalsSwiftBuild() async throws {
670+
#if os(Linux)
671+
if FileManager.default.contents(atPath: "/etc/system-release").map { String(decoding: $0, as: UTF8.self) == "Amazon Linux release 2 (Karoo)\n" } ?? false {
672+
throw XCTSkip("Skipping Swift Build testing on Amazon Linux because of platform issues.")
673+
}
674+
#endif
675+
try await fixture(name: "Miscellaneous/RootPackageWithConditionals") { path in
676+
_ = try await SwiftPM.Build.execute(["--build-system=swiftbuild"], packagePath: path, env: ["SWIFT_DRIVER_SWIFTSCAN_LIB" : "/this/is/a/bad/path"])
677+
}
678+
}
668679
}

0 commit comments

Comments
 (0)