@@ -270,6 +270,138 @@ final class CachingBuildTests: XCTestCase {
270
270
}
271
271
}
272
272
273
+ /// Test generation of explicit module build jobs for dependency modules when the driver
274
+ /// is invoked with -explicit-module-build, -verify-emitted-module-interface and -enable-library-evolution.
275
+ func testExplicitModuleVerifyInterfaceJobs( ) throws {
276
+ try withTemporaryDirectory { path in
277
+ let main = path. appending ( component: " testExplicitModuleVerifyInterfaceJobs.swift " )
278
+ try localFileSystem. writeFileContents ( main) {
279
+ $0 <<< " import C; "
280
+ $0 <<< " import E; "
281
+ $0 <<< " import G; "
282
+ }
283
+
284
+ let swiftModuleInterfacesPath : AbsolutePath =
285
+ testInputsPath. appending ( component: " ExplicitModuleBuilds " )
286
+ . appending ( component: " Swift " )
287
+ let cHeadersPath : AbsolutePath =
288
+ testInputsPath. appending ( component: " ExplicitModuleBuilds " )
289
+ . appending ( component: " CHeaders " )
290
+ let casPath = path. appending ( component: " cas " )
291
+ let swiftInterfacePath : AbsolutePath = path. appending ( component: " testExplicitModuleVerifyInterfaceJobs.swiftinterface " )
292
+ let privateSwiftInterfacePath : AbsolutePath = path. appending ( component: " testExplicitModuleVerifyInterfaceJobs.private.swiftinterface " )
293
+ let sdkArgumentsForTesting = ( try ? Driver . sdkArgumentsForTesting ( ) ) ?? [ ]
294
+ var driver = try Driver ( args: [ " swiftc " ,
295
+ " -target " , " x86_64-apple-macosx11.0 " ,
296
+ " -I " , cHeadersPath. nativePathString ( escaped: true ) ,
297
+ " -I " , swiftModuleInterfacesPath. nativePathString ( escaped: true ) ,
298
+ " -emit-module-interface-path " , swiftInterfacePath. nativePathString ( escaped: true ) ,
299
+ " -emit-private-module-interface-path " , privateSwiftInterfacePath. nativePathString ( escaped: true ) ,
300
+ " -explicit-module-build " , " -verify-emitted-module-interface " ,
301
+ " -enable-library-evolution " ,
302
+ " -cache-compile-job " , " -cas-path " , casPath. nativePathString ( escaped: true ) ,
303
+ main. nativePathString ( escaped: true ) ] + sdkArgumentsForTesting)
304
+
305
+ let jobs = try driver. planBuild ( )
306
+ // Figure out which Triples to use.
307
+ let dependencyGraph = try driver. gatherModuleDependencies ( )
308
+ let mainModuleInfo = try dependencyGraph. moduleInfo ( of: . swift( " testExplicitModuleVerifyInterfaceJobs " ) )
309
+ guard case . swift( _) = mainModuleInfo. details else {
310
+ XCTFail ( " Main module does not have Swift details field " )
311
+ return
312
+ }
313
+
314
+ for job in jobs {
315
+ if ( job. outputs. count == 0 ) {
316
+ // This is the verify module job as it should be the only job scheduled to have no output.
317
+ XCTAssertTrue ( job. kind == . verifyModuleInterface)
318
+ // Check the explicit module flags exists.
319
+ XCTAssertTrue ( job. commandLine. contains ( . flag( String ( " -explicit-interface-module-build " ) ) ) )
320
+ XCTAssertTrue ( job. commandLine. contains ( . flag( String ( " -explicit-swift-module-map-file " ) ) ) )
321
+ XCTAssertTrue ( job. commandLine. contains ( . flag( String ( " -disable-implicit-swift-modules " ) ) ) )
322
+ XCTAssertTrue ( job. commandLine. contains ( . flag( String ( " -input-file-key " ) ) ) )
323
+ continue
324
+ }
325
+ let outputFilePath = job. outputs [ 0 ] . file
326
+
327
+ // Swift dependencies
328
+ if outputFilePath. extension != nil ,
329
+ outputFilePath. extension! == FileType . swiftModule. rawValue {
330
+ if pathMatchesSwiftModule ( path: outputFilePath, " A " ) {
331
+ try checkCachingBuildJob ( job: job, moduleId: . swift( " A " ) ,
332
+ dependencyGraph: dependencyGraph)
333
+ } else if pathMatchesSwiftModule ( path: outputFilePath, " E " ) {
334
+ try checkCachingBuildJob ( job: job, moduleId: . swift( " E " ) ,
335
+ dependencyGraph: dependencyGraph)
336
+ } else if pathMatchesSwiftModule ( path: outputFilePath, " G " ) {
337
+ try checkCachingBuildJob ( job: job, moduleId: . swift( " G " ) ,
338
+ dependencyGraph: dependencyGraph)
339
+ } else if pathMatchesSwiftModule ( path: outputFilePath, " Swift " ) {
340
+ try checkCachingBuildJob ( job: job, moduleId: . swift( " Swift " ) ,
341
+ dependencyGraph: dependencyGraph)
342
+ } else if pathMatchesSwiftModule ( path: outputFilePath, " _Concurrency " ) {
343
+ try checkCachingBuildJob ( job: job, moduleId: . swift( " _Concurrency " ) ,
344
+ dependencyGraph: dependencyGraph)
345
+ } else if pathMatchesSwiftModule ( path: outputFilePath, " _StringProcessing " ) {
346
+ try checkCachingBuildJob ( job: job, moduleId: . swift( " _StringProcessing " ) ,
347
+ dependencyGraph: dependencyGraph)
348
+ } else if pathMatchesSwiftModule ( path: outputFilePath, " SwiftOnoneSupport " ) {
349
+ try checkCachingBuildJob ( job: job, moduleId: . swift( " SwiftOnoneSupport " ) ,
350
+ dependencyGraph: dependencyGraph)
351
+ }
352
+ // Clang Dependencies
353
+ } else if let outputExtension = outputFilePath. extension,
354
+ outputExtension == FileType . pcm. rawValue {
355
+ let relativeOutputPathFileName = outputFilePath. basename
356
+ if relativeOutputPathFileName. starts ( with: " A- " ) {
357
+ try checkCachingBuildJob ( job: job, moduleId: . clang( " A " ) ,
358
+ dependencyGraph: dependencyGraph)
359
+ }
360
+ else if relativeOutputPathFileName. starts ( with: " B- " ) {
361
+ try checkCachingBuildJob ( job: job, moduleId: . clang( " B " ) ,
362
+ dependencyGraph: dependencyGraph)
363
+ }
364
+ else if relativeOutputPathFileName. starts ( with: " C- " ) {
365
+ try checkCachingBuildJob ( job: job, moduleId: . clang( " C " ) ,
366
+ dependencyGraph: dependencyGraph)
367
+ }
368
+ else if relativeOutputPathFileName. starts ( with: " G- " ) {
369
+ try checkCachingBuildJob ( job: job, moduleId: . clang( " G " ) ,
370
+ dependencyGraph: dependencyGraph)
371
+ }
372
+ else if relativeOutputPathFileName. starts ( with: " F- " ) {
373
+ try checkCachingBuildJob ( job: job, moduleId: . clang( " F " ) ,
374
+ dependencyGraph: dependencyGraph)
375
+ }
376
+ else if relativeOutputPathFileName. starts ( with: " SwiftShims- " ) {
377
+ try checkCachingBuildJob ( job: job, moduleId: . clang( " SwiftShims " ) ,
378
+ dependencyGraph: dependencyGraph)
379
+ }
380
+ else if relativeOutputPathFileName. starts ( with: " _SwiftConcurrencyShims- " ) {
381
+ try checkCachingBuildJob ( job: job, moduleId: . clang( " _SwiftConcurrencyShims " ) ,
382
+ dependencyGraph: dependencyGraph)
383
+ }
384
+ else {
385
+ XCTFail ( " Unexpected module dependency build job output: \( outputFilePath) " )
386
+ }
387
+ } else {
388
+ switch ( outputFilePath) {
389
+ case . relative( RelativePath ( " testExplicitModuleVerifyInterfaceJobs " ) ) :
390
+ XCTAssertTrue ( driver. isExplicitMainModuleJob ( job: job) )
391
+ XCTAssertEqual ( job. kind, . link)
392
+ case . temporary( _) :
393
+ let baseName = " testExplicitModuleVerifyInterfaceJobs "
394
+ XCTAssertTrue ( matchTemporary ( outputFilePath, basename: baseName, fileExtension: " o " ) ||
395
+ matchTemporary ( outputFilePath, basename: baseName, fileExtension: " autolink " ) )
396
+ default :
397
+ XCTFail ( " Unexpected module dependency build job output: \( outputFilePath) " )
398
+ }
399
+ }
400
+ }
401
+ }
402
+ }
403
+
404
+
273
405
func testCacheBuildEndToEndBuild( ) throws {
274
406
try withTemporaryDirectory { path in
275
407
try localFileSystem. changeCurrentWorkingDirectory ( to: path)
0 commit comments