@@ -106,26 +106,13 @@ extension LLBuildManifestBuilder {
106
106
inputs: [ Node ] ,
107
107
resolver: ArgsResolver ,
108
108
isMainModule: ( Job ) -> Bool ,
109
- uniqueExplicitDependencyTracker: UniqueExplicitDependencyJobTracker ? = nil
110
109
) throws {
111
110
// Add build jobs to the manifest
112
111
for job in jobs {
113
112
let tool = try resolver. resolve ( . path( job. tool) )
114
113
let commandLine = try job. commandLine. map { try resolver. resolve ( $0) }
115
114
let arguments = [ tool] + commandLine
116
115
117
- // Check if an explicit pre-build dependency job has already been
118
- // added as a part of this build.
119
- if let uniqueExplicitDependencyTracker,
120
- job. isExplicitDependencyPreBuildJob
121
- {
122
- if try ! uniqueExplicitDependencyTracker. registerExplicitDependencyBuildJob ( job) {
123
- // This is a duplicate of a previously-seen identical job.
124
- // Skip adding it to the manifest
125
- continue
126
- }
127
- }
128
-
129
116
let jobInputs = try job. inputs. map { try $0. resolveToNode ( fileSystem: self . fileSystem) }
130
117
let jobOutputs = try job. outputs. map { try $0. resolveToNode ( fileSystem: self . fileSystem) }
131
118
@@ -137,7 +124,7 @@ extension LLBuildManifestBuilder {
137
124
// common intermediate dependency modules, such dependencies can lead
138
125
// to cycles in the resulting manifest.
139
126
var manifestNodeInputs : [ Node ] = [ ]
140
- if targetDescription . buildParameters . driverParameters . useExplicitModuleBuild && !isMainModule( job) {
127
+ if !isMainModule( job) {
141
128
manifestNodeInputs = jobInputs
142
129
} else {
143
130
manifestNodeInputs = ( inputs + jobInputs) . uniqued ( )
@@ -172,207 +159,6 @@ extension LLBuildManifestBuilder {
172
159
}
173
160
}
174
161
175
- // Building a Swift module in Explicit Module Build mode requires passing all of its module
176
- // dependencies as explicit arguments to the build command. Thus, building a SwiftPM package
177
- // with multiple inter-dependent targets requires that each module’s build job must
178
- // have its module dependencies’ modules passed into it as explicit module dependencies.
179
- // Because none of the targets have been built yet, a given target's dependency scanning
180
- // action will not be able to discover its module dependencies' modules. Instead, it is
181
- // SwiftPM's responsibility to communicate to the driver, when planning a given module's
182
- // build, that this module has dependencies that are other targets, along with a list of
183
- // future artifacts of such dependencies (.swiftmodule and .pcm files).
184
- // The driver will then use those artifacts as explicit inputs to its module’s build jobs.
185
- //
186
- // Consider an example SwiftPM package with two targets: module B, and module A, where A
187
- // depends on B:
188
- // SwiftPM will process targets in a topological order and “bubble-up” each module’s
189
- // inter-module dependency graph to its dependencies. First, SwiftPM will process B, and be
190
- // able to plan its full build because it does not have any module dependencies. Then the
191
- // driver is tasked with planning a build for A. SwiftPM will pass as input to the driver
192
- // the module dependency graph of its module’s dependencies, in this case, just the
193
- // dependency graph of B. The driver is then responsible for the necessary post-processing
194
- // to merge the dependency graphs and plan the build for A, using artifacts of B as explicit
195
- // inputs.
196
- public func addTargetsToExplicitBuildManifest( ) throws {
197
- // Sort the product targets in topological order in order to collect and "bubble up"
198
- // their respective dependency graphs to the depending targets.
199
- let allPackageDependencies = self . plan. targets. flatMap { $0. recursiveDependencies ( using: self . plan) }
200
-
201
- // Instantiate the inter-module dependency oracle which will cache commonly-scanned
202
- // modules across targets' Driver instances.
203
- let dependencyOracle = InterModuleDependencyOracle ( )
204
-
205
- // Explicit dependency pre-build jobs may be common to multiple targets.
206
- // We de-duplicate them here to avoid adding identical entries to the
207
- // downstream LLBuild manifest
208
- let explicitDependencyJobTracker = UniqueExplicitDependencyJobTracker ( )
209
-
210
- // Create commands for all module descriptions in the plan.
211
- for dependency in allPackageDependencies. reversed ( ) {
212
- guard case . module( let module, let description) = dependency else {
213
- // Product dependency build jobs are added after the fact.
214
- // Targets that depend on product dependencies will expand the corresponding
215
- // product into its constituent targets.
216
- continue
217
- }
218
-
219
- guard module. underlying. type != . systemModule,
220
- module. underlying. type != . binary
221
- else {
222
- // Much like non-Swift targets, system modules will consist of a modulemap
223
- // somewhere in the filesystem, with the path to that module being either
224
- // manually-specified or computed based on the system module type (apt, brew).
225
- // Similarly, binary targets will bring in an .xcframework, the contents of
226
- // which will be exposed via search paths.
227
- //
228
- // In both cases, the dependency scanning action in the driver will be automatically
229
- // be able to detect such targets' modules.
230
- continue
231
- }
232
-
233
- guard let description else {
234
- throw InternalError ( " Expected description for module \( module) " )
235
- }
236
-
237
- switch description {
238
- case . swift( let desc) :
239
- try self . createExplicitSwiftTargetCompileCommand (
240
- description: desc,
241
- dependencyOracle: dependencyOracle,
242
- explicitDependencyJobTracker: explicitDependencyJobTracker
243
- )
244
- case . clang( let desc) :
245
- try self . createClangCompileCommand ( desc)
246
- }
247
- }
248
- }
249
-
250
- private func createExplicitSwiftTargetCompileCommand(
251
- description: SwiftModuleBuildDescription ,
252
- dependencyOracle: InterModuleDependencyOracle ,
253
- explicitDependencyJobTracker: UniqueExplicitDependencyJobTracker ?
254
- ) throws {
255
- // Inputs.
256
- let inputs = try self . computeSwiftCompileCmdInputs ( description)
257
-
258
- // Outputs.
259
- let objectNodes = try description. objects. map ( Node . file)
260
- let moduleNode = Node . file ( description. moduleOutputPath)
261
- let cmdOutputs = objectNodes + [ moduleNode]
262
-
263
- // Commands.
264
- try addExplicitBuildSwiftCmds (
265
- description,
266
- inputs: inputs,
267
- dependencyOracle: dependencyOracle,
268
- explicitDependencyJobTracker: explicitDependencyJobTracker
269
- )
270
-
271
- self . addTargetCmd ( description, cmdOutputs: cmdOutputs)
272
- try self . addModuleWrapCmd ( description)
273
- }
274
-
275
- private func addExplicitBuildSwiftCmds(
276
- _ targetDescription: SwiftModuleBuildDescription ,
277
- inputs: [ Node ] ,
278
- dependencyOracle: InterModuleDependencyOracle ,
279
- explicitDependencyJobTracker: UniqueExplicitDependencyJobTracker ? = nil
280
- ) throws {
281
- // Pass the driver its external dependencies (module dependencies)
282
- var dependencyModuleDetailsMap : SwiftDriver . ExternalTargetModuleDetailsMap = [ : ]
283
- // Collect paths for module dependencies of this module (direct and transitive)
284
- try self . collectTargetDependencyModuleDetails (
285
- for: . swift( targetDescription) ,
286
- dependencyModuleDetailsMap: & dependencyModuleDetailsMap
287
- )
288
-
289
- // Compute the set of frontend
290
- // jobs needed to build this Swift module.
291
- var commandLine = try targetDescription. emitCommandLine ( )
292
- commandLine. append ( " -driver-use-frontend-path " )
293
- commandLine. append ( targetDescription. buildParameters. toolchain. swiftCompilerPath. pathString)
294
- commandLine. append ( " -experimental-explicit-module-build " )
295
- let resolver = try ArgsResolver ( fileSystem: self . fileSystem)
296
- let executor = SPMSwiftDriverExecutor (
297
- resolver: resolver,
298
- fileSystem: self . fileSystem,
299
- env: Environment . current
300
- )
301
- var driver = try Driver (
302
- args: commandLine,
303
- fileSystem: self . fileSystem,
304
- executor: executor,
305
- compilerIntegratedTooling: false ,
306
- externalTargetModuleDetailsMap: dependencyModuleDetailsMap,
307
- interModuleDependencyOracle: dependencyOracle
308
- )
309
- try driver. checkLDPathOption ( commandLine: commandLine)
310
-
311
- let jobs = try driver. planBuild ( )
312
- try self . addSwiftDriverJobs (
313
- for: targetDescription,
314
- jobs: jobs,
315
- inputs: inputs,
316
- resolver: resolver,
317
- isMainModule: { driver. isExplicitMainModuleJob ( job: $0) } ,
318
- uniqueExplicitDependencyTracker: explicitDependencyJobTracker
319
- )
320
- }
321
-
322
- /// Collect a map from all module dependencies of the specified module to the build planning artifacts for said
323
- /// dependency,
324
- /// in the form of a path to a .swiftmodule file and the dependency's InterModuleDependencyGraph.
325
- private func collectTargetDependencyModuleDetails(
326
- for targetDescription: ModuleBuildDescription ,
327
- dependencyModuleDetailsMap: inout SwiftDriver . ExternalTargetModuleDetailsMap
328
- ) throws {
329
- for dependency in targetDescription. dependencies ( using: self . plan) {
330
- switch dependency {
331
- case . product( let product, let productDescription) :
332
- for productDependency in product. modules {
333
- guard let dependencyModuleDescription = self . plan. description (
334
- for: productDependency,
335
- context: productDescription? . destination ?? targetDescription. destination
336
- ) else
337
- {
338
- throw InternalError ( " unknown dependency target for \( productDependency) " )
339
- }
340
- try self . addTargetDependencyInfo (
341
- for: dependencyModuleDescription,
342
- dependencyModuleDetailsMap: & dependencyModuleDetailsMap
343
- )
344
- }
345
- case . module( let dependencyModule, let dependencyDescription) :
346
- guard let dependencyDescription else {
347
- throw InternalError ( " No build description for module: \( dependencyModule) " )
348
- }
349
- // Product dependencies are broken down into the targets that make them up.
350
- try self . addTargetDependencyInfo (
351
- for: dependencyDescription,
352
- dependencyModuleDetailsMap: & dependencyModuleDetailsMap
353
- )
354
- }
355
- }
356
- }
357
-
358
- private func addTargetDependencyInfo(
359
- for targetDescription: ModuleBuildDescription ,
360
- dependencyModuleDetailsMap: inout SwiftDriver . ExternalTargetModuleDetailsMap
361
- ) throws {
362
- guard case . swift( let dependencySwiftTargetDescription) = targetDescription else {
363
- return
364
- }
365
- dependencyModuleDetailsMap [ ModuleDependencyId . swiftPlaceholder ( targetDescription. module. c99name) ] =
366
- SwiftDriver . ExternalTargetModuleDetails (
367
- path: TSCAbsolutePath ( dependencySwiftTargetDescription. moduleOutputPath) ,
368
- isFramework: false
369
- )
370
- try self . collectTargetDependencyModuleDetails (
371
- for: targetDescription,
372
- dependencyModuleDetailsMap: & dependencyModuleDetailsMap
373
- )
374
- }
375
-
376
162
private func addCmdWithBuiltinSwiftTool(
377
163
_ target: SwiftModuleBuildDescription ,
378
164
inputs: [ Node ] ,
@@ -581,32 +367,6 @@ extension LLBuildManifestBuilder {
581
367
}
582
368
}
583
369
584
- extension SwiftDriver . Job {
585
- fileprivate var isExplicitDependencyPreBuildJob : Bool {
586
- ( kind == . emitModule && inputs. contains { $0. file. extension == " swiftinterface " } ) || kind == . generatePCM
587
- }
588
- }
589
-
590
- /// A simple mechanism to keep track of already-known explicit module pre-build jobs.
591
- /// It uses the output filename of the job (either a `.swiftmodule` or a `.pcm`) for uniqueness,
592
- /// because the SwiftDriver encodes the module's context hash into this filename. Any two jobs
593
- /// producing an binary module file with an identical name are therefore duplicate
594
- private class UniqueExplicitDependencyJobTracker {
595
- private var uniqueDependencyModuleIDSet : Set < Int > = [ ]
596
-
597
- /// Registers the input Job with the tracker. Returns `false` if this job is already known
598
- func registerExplicitDependencyBuildJob( _ job: SwiftDriver . Job ) throws -> Bool {
599
- guard job. isExplicitDependencyPreBuildJob,
600
- let soleOutput = job. outputs. spm_only
601
- else {
602
- throw InternalError ( " Expected explicit module dependency build job " )
603
- }
604
- let jobUniqueID = soleOutput. file. basename. hashValue
605
- let ( new, _) = self . uniqueDependencyModuleIDSet. insert ( jobUniqueID)
606
- return new
607
- }
608
- }
609
-
610
370
extension TypedVirtualPath {
611
371
/// Resolve a typed virtual path provided by the Swift driver to
612
372
/// a node in the build graph.
0 commit comments