@@ -36,6 +36,11 @@ import DriverSupport
36
36
import SwiftDriver
37
37
#endif
38
38
39
+ struct BuildManifestDescription {
40
+ let description : BuildDescription
41
+ let manifest : LLBuildManifest
42
+ }
43
+
39
44
public final class BuildOperation : PackageStructureDelegate , SPMBuildCore . BuildSystem , BuildErrorAdviceProvider {
40
45
/// The delegate used by the build system.
41
46
public weak var delegate : SPMBuildCore . BuildSystemDelegate ?
@@ -47,7 +52,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
47
52
let toolsBuildParameters : BuildParameters
48
53
49
54
/// The closure for loading the package graph.
50
- let packageGraphLoader : ( ) throws -> ModulesGraph
55
+ let packageGraphLoader : ( ) async throws -> ModulesGraph
51
56
52
57
/// the plugin configuration for build plugins
53
58
let pluginConfiguration : PluginConfiguration ?
@@ -94,7 +99,9 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
94
99
private let observabilityScope : ObservabilityScope
95
100
96
101
public var builtTestProducts : [ BuiltTestProduct ] {
97
- ( try ? getBuildDescription ( ) ) ? . builtTestProducts ?? [ ]
102
+ get async {
103
+ ( try ? await getBuildDescription ( ) ) ? . builtTestProducts ?? [ ]
104
+ }
98
105
}
99
106
100
107
/// File rules to determine resource handling behavior.
@@ -113,7 +120,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
113
120
productsBuildParameters: BuildParameters ,
114
121
toolsBuildParameters: BuildParameters ,
115
122
cacheBuildManifest: Bool ,
116
- packageGraphLoader: @escaping ( ) throws -> ModulesGraph ,
123
+ packageGraphLoader: @escaping ( ) async throws -> ModulesGraph ,
117
124
pluginConfiguration: PluginConfiguration ? = . none,
118
125
scratchDirectory: AbsolutePath ,
119
126
additionalFileRules: [ FileRuleDescription ] ,
@@ -148,18 +155,20 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
148
155
self . observabilityScope = observabilityScope. makeChildScope ( description: " Build Operation " )
149
156
}
150
157
151
- public func getPackageGraph( ) throws -> ModulesGraph {
152
- try self . packageGraph. memoize {
153
- try self . packageGraphLoader ( )
158
+ public var modulesGraph : ModulesGraph {
159
+ get async throws {
160
+ try await self . packageGraph. memoize {
161
+ try await self . packageGraphLoader ( )
162
+ }
154
163
}
155
164
}
156
165
157
166
/// Compute and return the latest build description.
158
167
///
159
168
/// This will try skip build planning if build manifest caching is enabled
160
169
/// and the package structure hasn't changed.
161
- public func getBuildDescription( subset: BuildSubset ? = nil ) throws -> BuildDescription {
162
- return try self . buildDescription. memoize {
170
+ public func getBuildDescription( subset: BuildSubset ? = nil ) async throws -> BuildDescription {
171
+ return try await self . buildDescription. memoize {
163
172
if self . cacheBuildManifest {
164
173
do {
165
174
// if buildPackageStructure returns a valid description we use that, otherwise we perform full planning
@@ -182,12 +191,12 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
182
191
}
183
192
}
184
193
// We need to perform actual planning if we reach here.
185
- return try self . plan ( subset: subset) . description
194
+ return try await self . plan ( subset: subset) . description
186
195
}
187
196
}
188
197
189
- public func getBuildManifest( ) throws -> LLBuildManifest {
190
- return try self . plan ( ) . manifest
198
+ public func getBuildManifest( ) async throws -> LLBuildManifest {
199
+ return try await self . plan ( ) . manifest
191
200
}
192
201
193
202
/// Cancel the active build operation.
@@ -337,7 +346,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
337
346
}
338
347
339
348
/// Perform a build using the given build description and subset.
340
- public func build( subset: BuildSubset ) throws {
349
+ public func build( subset: BuildSubset ) async throws {
341
350
guard !self . productsBuildParameters. shouldSkipBuilding else {
342
351
return
343
352
}
@@ -347,7 +356,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
347
356
// Get the build description (either a cached one or newly created).
348
357
349
358
// Get the build description
350
- let buildDescription = try getBuildDescription ( subset: subset)
359
+ let buildDescription = try await getBuildDescription ( subset: subset)
351
360
352
361
// Verify dependency imports on the described targets
353
362
try verifyTargetImports ( in: buildDescription)
@@ -361,15 +370,15 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
361
370
// If any plugins are part of the build set, compile them now to surface
362
371
// any errors up-front. Returns true if we should proceed with the build
363
372
// or false if not. It will already have thrown any appropriate error.
364
- guard try self . compilePlugins ( in: subset) else {
373
+ guard try await self . compilePlugins ( in: subset) else {
365
374
return
366
375
}
367
376
368
377
// delegate is only available after createBuildSystem is called
369
378
progressTracker. buildStart ( configuration: self . productsBuildParameters. configuration)
370
379
371
380
// Perform the build.
372
- let llbuildTarget = try computeLLBuildTargetName ( for: subset)
381
+ let llbuildTarget = try await computeLLBuildTargetName ( for: subset)
373
382
let success = buildSystem. build ( target: llbuildTarget)
374
383
375
384
let duration = buildStartTime. distance ( to: . now( ) )
@@ -422,10 +431,10 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
422
431
/// true if the build should proceed. Throws an error in case of failure. A
423
432
/// reason why the build might not proceed even on success is if only plugins
424
433
/// should be compiled.
425
- func compilePlugins( in subset: BuildSubset ) throws -> Bool {
434
+ func compilePlugins( in subset: BuildSubset ) async throws -> Bool {
426
435
// Figure out what, if any, plugin descriptions to compile, and whether
427
436
// to continue building after that based on the subset.
428
- let allPlugins = try getBuildDescription ( ) . pluginDescriptions
437
+ let allPlugins = try await getBuildDescription ( ) . pluginDescriptions
429
438
let pluginsToCompile : [ PluginDescription ]
430
439
let continueBuilding : Bool
431
440
switch subset {
@@ -518,15 +527,15 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
518
527
}
519
528
520
529
/// Compute the llbuild target name using the given subset.
521
- func computeLLBuildTargetName( for subset: BuildSubset ) throws -> String {
530
+ func computeLLBuildTargetName( for subset: BuildSubset ) async throws -> String {
522
531
switch subset {
523
532
case . allExcludingTests:
524
533
return LLBuildManifestBuilder . TargetKind. main. targetName
525
534
case . allIncludingTests:
526
535
return LLBuildManifestBuilder . TargetKind. test. targetName
527
536
case . product( let productName, let destination) :
528
537
// FIXME: This is super unfortunate that we might need to load the package graph.
529
- let graph = try getPackageGraph ( )
538
+ let graph = try await self . modulesGraph
530
539
531
540
let buildTriple : BuildTriple ? = if let destination {
532
541
destination == . host ? . tools : . destination
@@ -562,7 +571,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
562
571
return try product. getLLBuildTargetName ( buildParameters: buildParameters)
563
572
case . target( let targetName, let destination) :
564
573
// FIXME: This is super unfortunate that we might need to load the package graph.
565
- let graph = try getPackageGraph ( )
574
+ let graph = try await self . modulesGraph
566
575
567
576
let buildTriple : BuildTriple ? = if let destination {
568
577
destination == . host ? . tools : . destination
@@ -591,9 +600,9 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
591
600
}
592
601
593
602
/// Create the build plan and return the build description.
594
- private func plan( subset: BuildSubset ? = nil ) throws -> ( description : BuildDescription , manifest : LLBuildManifest ) {
603
+ private func plan( subset: BuildSubset ? = nil ) async throws -> BuildManifestDescription {
595
604
// Load the package graph.
596
- let graph = try getPackageGraph ( )
605
+ let graph = try await self . modulesGraph
597
606
let buildToolPluginInvocationResults : [ ResolvedModule . ID : ( target: ResolvedModule , results: [ BuildToolPluginInvocationResult ] ) ]
598
607
let prebuildCommandResults : [ ResolvedModule . ID : [ PrebuildCommandResult ] ]
599
608
// Invoke any build tool plugins in the graph to generate prebuild commands and build commands.
@@ -624,7 +633,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
624
633
observabilityScope: self . observabilityScope
625
634
)
626
635
627
- buildToolPluginInvocationResults = try graph. invokeBuildToolPlugins (
636
+ buildToolPluginInvocationResults = try await graph. invokeBuildToolPlugins (
628
637
outputDir: pluginConfiguration. workDirectory. appending ( " outputs " ) ,
629
638
buildParameters: pluginsBuildParameters,
630
639
additionalFileRules: self . additionalFileRules,
@@ -634,7 +643,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
634
643
observabilityScope: self . observabilityScope,
635
644
fileSystem: self . fileSystem
636
645
) { name, path in
637
- try buildOperationForPluginDependencies. build ( subset: . product( name, for: . host) )
646
+ try await buildOperationForPluginDependencies. build ( subset: . product( name, for: . host) )
638
647
if let builtTool = try buildOperationForPluginDependencies. buildPlan. buildProducts. first ( where: {
639
648
$0. product. name == name && $0. buildParameters. destination == . host
640
649
} ) {
@@ -743,7 +752,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
743
752
)
744
753
745
754
// Finally create the llbuild manifest from the plan.
746
- return ( buildDescription, buildManifest)
755
+ return . init ( description : buildDescription, manifest : buildManifest)
747
756
}
748
757
749
758
/// Build the package structure target.
@@ -871,7 +880,16 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
871
880
872
881
public func packageStructureChanged( ) -> Bool {
873
882
do {
874
- _ = try self . plan ( )
883
+ _ = try temp_await { ( callback: @escaping ( Result < BuildManifestDescription , any Error > ) -> Void ) in
884
+ _Concurrency. Task {
885
+ do {
886
+ let value = try await self . plan ( )
887
+ callback ( . success( value) )
888
+ } catch {
889
+ callback ( . failure( error) )
890
+ }
891
+ }
892
+ }
875
893
}
876
894
catch Diagnostics . fatalError {
877
895
return false
0 commit comments