@@ -191,8 +191,10 @@ extension LLBuildManifestBuilder {
191
191
public func addTargetsToExplicitBuildManifest( ) throws {
192
192
// Sort the product targets in topological order in order to collect and "bubble up"
193
193
// their respective dependency graphs to the depending targets.
194
- let allPackageDependencies = self . plan. targets. flatMap { $0. recursiveDependencies ( using: self . plan) }
195
-
194
+ let nodes = self . plan. targets. compactMap {
195
+ ResolvedModule . Dependency. module ( $0. module, conditions: [ ] )
196
+ }
197
+ let allPackageDependencies = try topologicalSort ( nodes, successors: { $0. dependencies } )
196
198
// Instantiate the inter-module dependency oracle which will cache commonly-scanned
197
199
// modules across targets' Driver instances.
198
200
let dependencyOracle = InterModuleDependencyOracle ( )
@@ -204,15 +206,14 @@ extension LLBuildManifestBuilder {
204
206
205
207
// Create commands for all module descriptions in the plan.
206
208
for dependency in allPackageDependencies. reversed ( ) {
207
- guard case . module( let module , let description ) = dependency else {
209
+ guard case . module( let target , _ ) = dependency else {
208
210
// Product dependency build jobs are added after the fact.
209
211
// Targets that depend on product dependencies will expand the corresponding
210
212
// product into its constituent targets.
211
213
continue
212
214
}
213
-
214
- guard module. underlying. type != . systemModule,
215
- module. underlying. type != . binary
215
+ guard target. underlying. type != . systemModule,
216
+ target. underlying. type != . binary
216
217
else {
217
218
// Much like non-Swift targets, system modules will consist of a modulemap
218
219
// somewhere in the filesystem, with the path to that module being either
@@ -224,11 +225,9 @@ extension LLBuildManifestBuilder {
224
225
// be able to detect such targets' modules.
225
226
continue
226
227
}
227
-
228
- guard let description else {
229
- throw InternalError ( " Expected description for module \( module) " )
228
+ guard let description = plan. targetMap [ target. id] else {
229
+ throw InternalError ( " Expected description for target \( target) " )
230
230
}
231
-
232
231
switch description {
233
232
case . swift( let desc) :
234
233
try self . createExplicitSwiftTargetCompileCommand (
@@ -320,29 +319,32 @@ extension LLBuildManifestBuilder {
320
319
for targetDescription: ModuleBuildDescription ,
321
320
dependencyModuleDetailsMap: inout SwiftDriver . ExternalTargetModuleDetailsMap
322
321
) throws {
323
- for dependency in targetDescription. dependencies ( using : self . plan ) {
322
+ for dependency in targetDescription. module . dependencies ( satisfying : targetDescription . buildParameters . buildEnvironment ) {
324
323
switch dependency {
325
- case . product( let product , let productDescription ) :
326
- for productDependency in product . modules {
327
- guard let dependencyModuleDescription = self . plan . description (
328
- for: productDependency ,
329
- context : productDescription ? . destination ?? targetDescription . destination
330
- ) else
331
- {
332
- throw InternalError ( " unknown dependency target for \( productDependency ) " )
324
+ case . product:
325
+ // Product dependencies are broken down into the targets that make them up.
326
+ guard let dependencyProduct = dependency . product else {
327
+ throw InternalError ( " unknown dependency product for \( dependency ) " )
328
+ }
329
+ for dependencyProductTarget in dependencyProduct . modules {
330
+ guard let dependencyTargetDescription = self . plan . targetMap [ dependencyProductTarget . id ] else {
331
+ throw InternalError ( " unknown dependency target for \( dependencyProductTarget ) " )
333
332
}
334
333
try self . addTargetDependencyInfo (
335
- for: dependencyModuleDescription ,
334
+ for: dependencyTargetDescription ,
336
335
dependencyModuleDetailsMap: & dependencyModuleDetailsMap
337
336
)
338
337
}
339
- case . module( let dependencyModule, let dependencyDescription) :
340
- guard let dependencyDescription else {
341
- throw InternalError ( " No build description for module: \( dependencyModule) " )
342
- }
338
+ case . module:
343
339
// Product dependencies are broken down into the targets that make them up.
340
+ guard
341
+ let dependencyTarget = dependency. module,
342
+ let dependencyTargetDescription = self . plan. targetMap [ dependencyTarget. id]
343
+ else {
344
+ throw InternalError ( " unknown dependency target for \( dependency) " )
345
+ }
344
346
try self . addTargetDependencyInfo (
345
- for: dependencyDescription ,
347
+ for: dependencyTargetDescription ,
346
348
dependencyModuleDetailsMap: & dependencyModuleDetailsMap
347
349
)
348
350
}
@@ -420,73 +422,63 @@ extension LLBuildManifestBuilder {
420
422
421
423
let prepareForIndexing = target. buildParameters. prepareForIndexing
422
424
423
- func addStaticTargetInputs( _ module : ResolvedModule , _ description : ModuleBuildDescription ? ) throws {
425
+ func addStaticTargetInputs( _ target : ResolvedModule ) throws {
424
426
// Ignore C Modules.
425
- if module . underlying is SystemLibraryModule { return }
427
+ if target . underlying is SystemLibraryModule { return }
426
428
// Ignore Binary Modules.
427
- if module . underlying is BinaryModule { return }
429
+ if target . underlying is BinaryModule { return }
428
430
// Ignore Plugin Modules.
429
- if module. underlying is PluginModule { return }
430
-
431
- guard let description else {
432
- throw InternalError ( " No build description for module: \( module) " )
433
- }
431
+ if target. underlying is PluginModule { return }
434
432
435
433
// Depend on the binary for executable targets.
436
- if module. type == . executable && prepareForIndexing == . off {
437
- // FIXME: Optimize. Build plan could build a mapping between executable modules
438
- // and their products to speed up search here, which is inefficient if the plan
439
- // contains a lot of products.
434
+ if target. type == . executable && prepareForIndexing == . off {
435
+ // FIXME: Optimize.
440
436
if let productDescription = try plan. productMap. values. first ( where: {
441
- try $0. product. type == . executable &&
442
- $0. product. executableModule. id == module. id &&
443
- $0. destination == description. destination
437
+ try $0. product. type == . executable && $0. product. executableModule. id == target. id
444
438
} ) {
445
439
try inputs. append ( file: productDescription. binaryPath)
446
440
}
447
441
return
448
442
}
449
443
450
- switch description {
451
- case . swift( let swiftDescription ) :
452
- inputs. append ( file: swiftDescription . moduleOutputPath)
453
- case . clang( let clangDescription ) :
444
+ switch self . plan . targetMap [ target . id ] {
445
+ case . swift( let target ) ? :
446
+ inputs. append ( file: target . moduleOutputPath)
447
+ case . clang( let target ) ? :
454
448
if prepareForIndexing != . off {
455
449
// In preparation, we're only building swiftmodules
456
450
// propagate the dependency to the header files in this target
457
- for header in clangDescription . clangTarget. headers {
451
+ for header in target . clangTarget. headers {
458
452
inputs. append ( file: header)
459
453
}
460
454
} else {
461
- for object in try clangDescription . objects {
455
+ for object in try target . objects {
462
456
inputs. append ( file: object)
463
457
}
464
458
}
459
+ case nil :
460
+ throw InternalError ( " unexpected: target \( target) not in target map \( self . plan. targetMap) " )
465
461
}
466
462
}
467
463
468
- for dependency in target. dependencies ( using : self . plan ) {
464
+ for dependency in target. target . dependencies ( satisfying : target . buildParameters . buildEnvironment ) {
469
465
switch dependency {
470
- case . module( let module , let description ) :
471
- try addStaticTargetInputs ( module , description )
466
+ case . module( let target , _ ) :
467
+ try addStaticTargetInputs ( target )
472
468
473
- case . product( let product, let productDescription ) :
469
+ case . product( let product, _ ) :
474
470
switch product. type {
475
471
case . executable, . snippet, . library( . dynamic) , . macro:
476
- guard let productDescription else {
477
- throw InternalError ( " No description for product: \( product) " )
472
+ guard let planProduct = plan . productMap [ product . id ] else {
473
+ throw InternalError ( " unknown product \( product) " )
478
474
}
479
475
// Establish a dependency on binary of the product.
480
- try inputs. append ( file: productDescription . binaryPath)
476
+ try inputs. append ( file: planProduct . binaryPath)
481
477
482
478
// For automatic and static libraries, and plugins, add their targets as static input.
483
479
case . library( . automatic) , . library( . static) , . plugin:
484
- for module in product. modules {
485
- let description = self . plan. description (
486
- for: module,
487
- context: product. type == . plugin ? . host : target. destination
488
- )
489
- try addStaticTargetInputs ( module, description)
480
+ for target in product. modules {
481
+ try addStaticTargetInputs ( target)
490
482
}
491
483
492
484
case . test:
0 commit comments