Skip to content

Commit 58a11b9

Browse files
committed
Check for the index workspace description rather than index arena
There's various paths that should be specific to the index workspace description rather than if the index arena is enabled. Specifically the recent change to replace parameters for host tools (#345) broke the *package* description as it uses the passed in run destination rather than configuring for all platforms. This replacement would then create two configured targets for macOS for the same target (one for the given run destination and one for the macOS platform that the index uses). This also changes the *target* description to only build for the run destination, which makes sense given its entire purpose is to be a replacement for the workspace description if it hasn't built yet (ie. it should be as fast as possible). Resolves rdar://149896775.
1 parent ac358da commit 58a11b9

File tree

5 files changed

+191
-13
lines changed

5 files changed

+191
-13
lines changed

Sources/SWBCore/BuildRequest.swift

+9
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,15 @@ public final class BuildRequest: CustomStringConvertible, Sendable {
248248
return parameters.action == .indexBuild
249249
}
250250

251+
/// Whether or not this request is for building the index workspace description (as opposed to the target or
252+
/// package description).
253+
///
254+
/// Note that this is only valid when *building* the description, subsequent requests that use it will have a run
255+
/// destination set (and thus return false).
256+
public var buildsIndexWorkspaceDescription: Bool {
257+
return enableIndexBuildArena && parameters.activeRunDestination == nil
258+
}
259+
251260
/// The quality-of-service to use for this request.
252261
public let qos: SWBQoS
253262

Sources/SWBCore/DependencyResolution.swift

+5-11
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ extension SpecializationParameters {
493493
self.workspaceContext = workspaceContext
494494
self.delegate = delegate
495495

496-
if buildRequest.enableIndexBuildArena {
496+
if buildRequest.buildsIndexWorkspaceDescription {
497497
// For the index build, multiple build parameters are applied during configuration of a target (to configure for multiple platforms) and the build parameters for each target in the build request is not relevant.
498498
// Keep this dictionary empty so that `LinkageDependencyResolver` fallbacks to using the build parameters of the configured targets, which are the relevant ones.
499499
self.buildParametersByTarget = [:]
@@ -507,7 +507,7 @@ extension SpecializationParameters {
507507

508508
self.defaultImposedParameters = SpecializationParameters.default(workspaceContext: workspaceContext, buildRequestContext: buildRequestContext, parameters: buildRequest.parameters)
509509

510-
if buildRequest.enableIndexBuildArena {
510+
if buildRequest.buildsIndexWorkspaceDescription {
511511
let hostOS = (try? workspaceContext.core.hostOperatingSystem.xcodePlatformName) ?? "unknown"
512512

513513
// Create the build parameters for each available platform.
@@ -577,20 +577,14 @@ extension SpecializationParameters {
577577
func lookupTopLevelConfiguredTarget(_ targetInfo: BuildRequest.BuildTargetInfo) -> [ConfiguredTarget] {
578578
guard !Task.isCancelled else { return [] }
579579
let (target, parameters) = (targetInfo.target, targetInfo.parameters)
580-
if !buildRequest.enableIndexBuildArena {
580+
if !buildRequest.buildsIndexWorkspaceDescription {
581581
// Top-level targets get defaults imposed, in case that they are themselves using "auto" anywhere.
582582
return [lookupConfiguredTarget(target, parameters: parameters, imposedParameters: defaultImposedParameters, isTopLevelLookup: true)]
583583
}
584584

585585
// Aggregate targets are only configured as dependencies.
586586
guard target.type != .aggregate else { return [] }
587587

588-
let isFromPackage = workspaceContext.workspace.project(for: target).isPackage
589-
if isFromPackage {
590-
// Configure top-level package targets using the run-destination of the build request.
591-
return [lookupConfiguredTarget(target, parameters: parameters, imposedParameters: defaultImposedParameters, isTopLevelLookup: true)]
592-
}
593-
594588
var configuredTargets: [ConfiguredTarget] = []
595589
let unconfiguredSettings = buildRequestContext.getCachedSettings(targetInfo.parameters, target: target)
596590
let unconfiguredSupportedPlatforms = unconfiguredSettings.globalScope.evaluate(BuiltinMacros.SUPPORTED_PLATFORMS)
@@ -757,7 +751,7 @@ extension SpecializationParameters {
757751
}
758752

759753
// At this point we know there is not a configured target for this target and parameters in our cache, so create one and return it.
760-
let configuredTarget = ConfiguredTarget(parameters: parameters, target: target, specializeGuidForActiveRunDestination: buildRequest.enableIndexBuildArena)
754+
let configuredTarget = ConfiguredTarget(parameters: parameters, target: target, specializeGuidForActiveRunDestination: buildRequest.buildsIndexWorkspaceDescription)
761755
configuredTargetsByTarget[configuredTarget.target, default: []].insert(configuredTarget)
762756
addSuperimposedProperties(for: configuredTarget, superimposedProperties: superimposedProperties)
763757
return configuredTarget
@@ -772,7 +766,7 @@ extension SpecializationParameters {
772766
}
773767

774768
var parameters = parameters
775-
if buildRequest.enableIndexBuildArena {
769+
if buildRequest.buildsIndexWorkspaceDescription {
776770
// Avoid forced propagation of "auto" overrides to targets that don't need them. If this is a host tool,
777771
// force its parameters to the host platform to avoid creating duplicate configured targets after it has
778772
// been specialized.

Sources/SWBTaskExecution/BuildDescriptionManager.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ package final class BuildDescriptionManager: Sendable {
285285
}
286286

287287
var isIndexWorkspaceDescription: Bool {
288-
return isForIndex && buildRequest.parameters.activeRunDestination == nil
288+
return buildRequest.buildsIndexWorkspaceDescription
289289
}
290290

291291
func signature(cacheDir: Path) throws -> BuildDescriptionSignature {

Tests/SWBBuildSystemTests/HostBuildToolBuildOperationTests.swift

+175
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,181 @@ fileprivate struct HostBuildToolBuildOperationTests: CoreBasedTests {
439439
}
440440
}
441441

442+
@Test(.requireSDKs(.macOS))
443+
func testHostToolsAndDependenciesAreBuiltDuringIndexingPreparationForPackage() async throws {
444+
try await withTemporaryDirectory { tmpDirPath async throws -> Void in
445+
let depPackage = try await TestPackageProject(
446+
"DepPackage",
447+
groupTree: TestGroup("Foo", children: [
448+
TestFile("transitivedep.swift"),
449+
TestFile("dep.swift"),
450+
]),
451+
buildConfigurations: [
452+
TestBuildConfiguration(
453+
"Debug",
454+
buildSettings: [
455+
"SWIFT_VERSION": swiftVersion,
456+
"GENERATE_INFOPLIST_FILE": "YES",
457+
"PRODUCT_NAME": "$(TARGET_NAME)",
458+
"CODE_SIGNING_ALLOWED": "NO",
459+
]),
460+
],
461+
targets: [
462+
TestStandardTarget("TransitivePackageDep", type: .objectFile, buildConfigurations: [
463+
TestBuildConfiguration(
464+
"Debug",
465+
buildSettings: [
466+
"SDKROOT": "auto",
467+
"SUPPORTED_PLATFORMS": "macosx iphoneos iphonesimulator",
468+
],
469+
impartedBuildProperties:
470+
TestImpartedBuildProperties(
471+
buildSettings: [
472+
"SWIFT_ACTIVE_COMPILATION_CONDITIONS": "IMPARTED_SETTINGS"
473+
])
474+
),
475+
], buildPhases: [
476+
TestSourcesBuildPhase(["transitivedep.swift"])
477+
]),
478+
TestStandardTarget("PackageDep", type: .staticLibrary, buildConfigurations: [
479+
TestBuildConfiguration(
480+
"Debug",
481+
buildSettings: [
482+
"SDKROOT": "auto",
483+
"SUPPORTED_PLATFORMS": "macosx iphoneos iphonesimulator",
484+
]),
485+
], buildPhases: [
486+
TestSourcesBuildPhase(["dep.swift"]),
487+
TestFrameworksBuildPhase([
488+
TestBuildFile(.target("TransitivePackageDep"))
489+
])
490+
], dependencies: [
491+
"TransitivePackageDep"
492+
]),
493+
TestPackageProductTarget("PackageDepProduct", frameworksBuildPhase:
494+
TestFrameworksBuildPhase([
495+
TestBuildFile(.target("PackageDep")),
496+
]
497+
), buildConfigurations: [
498+
TestBuildConfiguration(
499+
"Debug",
500+
buildSettings: [
501+
"SDKROOT": "auto",
502+
"SUPPORTED_PLATFORMS": "macosx iphoneos iphonesimulator",
503+
]),
504+
], dependencies: [
505+
"PackageDep"
506+
]),
507+
])
508+
509+
let hostToolsPackage = try await TestPackageProject(
510+
"HostToolsPackage",
511+
groupTree: TestGroup("Foo", children: [
512+
TestFile("tool.swift"),
513+
TestFile("lib.swift"),
514+
]),
515+
buildConfigurations: [
516+
TestBuildConfiguration(
517+
"Debug",
518+
buildSettings: [
519+
"SWIFT_VERSION": swiftVersion,
520+
"GENERATE_INFOPLIST_FILE": "YES",
521+
"PRODUCT_NAME": "$(TARGET_NAME)",
522+
"CODE_SIGNING_ALLOWED": "NO",
523+
]),
524+
],
525+
targets: [
526+
TestStandardTarget("HostTool", type: .hostBuildTool, buildConfigurations: [
527+
TestBuildConfiguration(
528+
"Debug",
529+
buildSettings: [
530+
"SDKROOT": "auto",
531+
])
532+
], buildPhases: [
533+
TestSourcesBuildPhase(["tool.swift"]),
534+
TestFrameworksBuildPhase([TestBuildFile(.target("PackageDepProduct"))])
535+
], dependencies: [
536+
"PackageDepProduct"
537+
]),
538+
TestStandardTarget("HostToolClientLib", type: .objectFile, buildConfigurations: [
539+
TestBuildConfiguration(
540+
"Debug",
541+
buildSettings: [
542+
"SDKROOT": "auto",
543+
"SUPPORTED_PLATFORMS": "macosx iphoneos iphonesimulator",
544+
]),
545+
], buildPhases: [
546+
TestSourcesBuildPhase(["lib.swift"]),
547+
], dependencies: [
548+
"HostTool"
549+
]),
550+
TestPackageProductTarget("HostToolClientLibProduct", frameworksBuildPhase:
551+
TestFrameworksBuildPhase([TestBuildFile(.target("HostToolClientLib"))]
552+
), buildConfigurations: [
553+
TestBuildConfiguration(
554+
"Debug",
555+
buildSettings: [
556+
"SDKROOT": "auto",
557+
"SUPPORTED_PLATFORMS": "macosx iphoneos iphonesimulator",
558+
]),
559+
], dependencies: [
560+
"HostToolClientLib"
561+
]),
562+
])
563+
564+
let testWorkspace = TestWorkspace("aWorkspace", sourceRoot: tmpDirPath.join("Test"), projects: [depPackage, hostToolsPackage])
565+
let tester = try await BuildOperationTester(getCore(), testWorkspace, simulated: false, systemInfo: .init(operatingSystemVersion: Version(99, 98, 97), productBuildVersion: "99A98", nativeArchitecture: Architecture.host.stringValue ?? "undefined_arch"))
566+
567+
try await tester.fs.writeFileContents(testWorkspace.sourceRoot.join("DepPackage/transitivedep.swift")) { stream in
568+
stream <<<
569+
"""
570+
public let transitiveDependencyMessage = "Hello from host tool transitive dependency!"
571+
"""
572+
}
573+
574+
try await tester.fs.writeFileContents(testWorkspace.sourceRoot.join("DepPackage/dep.swift")) { stream in
575+
stream <<<
576+
"""
577+
import TransitivePackageDep
578+
579+
public let dependencyMessage = "Hello from host tool dependency! " + transitiveDependencyMessage
580+
#if !IMPARTED_SETTINGS
581+
#error("settings not imparted")
582+
#endif
583+
"""
584+
}
585+
586+
try await tester.fs.writeFileContents(testWorkspace.sourceRoot.join("HostToolsPackage/tool.swift")) { stream in
587+
stream <<<
588+
"""
589+
import PackageDep
590+
591+
@main struct Foo {
592+
static func main() {
593+
print("Hello from host tool! " + dependencyMessage)
594+
}
595+
}
596+
"""
597+
}
598+
599+
try await tester.fs.writeFileContents(testWorkspace.sourceRoot.join("HostToolsPackage/lib.swift")) { stream in
600+
stream <<<
601+
"""
602+
public class MyClass {}
603+
"""
604+
}
605+
606+
try await tester.checkIndexBuild(prepareTargets: hostToolsPackage.targets.map(\.guid), workspaceOperation: false, runDestination: .anyMac, persistent: true) { results in
607+
results.checkNoDiagnostics()
608+
609+
results.checkTaskExists(.matchTargetName("HostTool"), .matchRuleType("Ld"))
610+
try results.checkTask(.matchTargetName("HostTool"), .matchRuleType(ProductPlan.preparedForIndexPreCompilationRuleName)) { task in
611+
try results.checkTaskFollows(task, .matchTargetName("PackageDep"), .matchRuleType("Libtool"))
612+
}
613+
}
614+
}
615+
}
616+
442617
@Test(.requireSDKs(.macOS))
443618
func hostToolsAreSkippedDuringIndexingPreparationWhenUnapproved() async throws {
444619
try await withTemporaryDirectory { tmpDirPath async throws -> Void in

Tests/SWBTaskConstructionTests/IndexBuildTaskConstructionTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ fileprivate struct IndexBuildTaskConstructionTests: CoreBasedTests {
366366
results.checkNoDiagnostics()
367367
}
368368

369-
try await tester.checkIndexBuild(targets: [fwkTarget1]) { results in
369+
try await tester.checkIndexBuild(targets: [fwkTarget1], workspaceOperation: true) { results in
370370
results.checkWriteAuxiliaryFileTask(.matchRulePattern(["WriteAuxiliaryFile", .suffix("VFS-iphonesimulator/all-product-headers.yaml")])) { task, contents in
371371
#expect(contents == vfs_sim)
372372
}

0 commit comments

Comments
 (0)