@@ -614,6 +614,135 @@ final class SwiftDriverTests: XCTestCase {
614614 }
615615 }
616616
617+ func testIndexUnitOutputPath( ) throws {
618+ let contents = """
619+ {
620+ " /tmp/main.swift " : {
621+ " object " : " /tmp/build1/main.o " ,
622+ " index-unit-output-path " : " /tmp/build2/main.o " ,
623+ },
624+ " /tmp/second.swift " : {
625+ " object " : " /tmp/build1/second.o " ,
626+ " index-unit-output-path " : " /tmp/build2/second.o " ,
627+ }
628+ }
629+ """
630+
631+ func getFileListElements( for filelistOpt: String , job: Job ) -> [ VirtualPath ] {
632+ let optIndex = job. commandLine. firstIndex ( of: . flag( filelistOpt) ) !
633+ let value = job. commandLine [ job. commandLine. index ( after: optIndex) ]
634+ guard case let . path( . fileList( _, valueFileList) ) = value else {
635+ XCTFail ( " Argument wasn't a filelist " )
636+ return [ ]
637+ }
638+ guard case let . list( inputs) = valueFileList else {
639+ XCTFail ( " FileList wasn't List " )
640+ return [ ]
641+ }
642+ return inputs
643+ }
644+
645+ try withTemporaryFile { file in
646+ try assertNoDiagnostics { diags in
647+ try localFileSystem. writeFileContents ( file. path) { $0 <<< contents }
648+
649+ // 1. Incremental mode (single primary file)
650+ // a) without filelists
651+ var driver = try Driver ( args: [
652+ " swiftc " , " -c " ,
653+ " -output-file-map " , file. path. pathString,
654+ " -module-name " , " test " , " /tmp/second.swift " , " /tmp/main.swift "
655+ ] )
656+ var jobs = try driver. planBuild ( )
657+ XCTAssertTrue ( jobs [ 0 ] . commandLine. contains ( subsequence: [ " -o " , . path( . absolute( . init( " /tmp/build1/second.o " ) ) ) ] ) )
658+ XCTAssertTrue ( jobs [ 1 ] . commandLine. contains ( subsequence: [ " -o " , . path( . absolute( . init( " /tmp/build1/main.o " ) ) ) ] ) )
659+ XCTAssertTrue ( jobs [ 0 ] . commandLine. contains ( subsequence: [ " -index-unit-output-path " , . path( . absolute( . init( " /tmp/build2/second.o " ) ) ) ] ) )
660+ XCTAssertTrue ( jobs [ 1 ] . commandLine. contains ( subsequence: [ " -index-unit-output-path " , . path( . absolute( . init( " /tmp/build2/main.o " ) ) ) ] ) )
661+
662+ // b) with filelists
663+ driver = try Driver ( args: [
664+ " swiftc " , " -c " , " -driver-filelist-threshold=0 " ,
665+ " -output-file-map " , file. path. pathString,
666+ " -module-name " , " test " , " /tmp/second.swift " , " /tmp/main.swift "
667+ ] )
668+ jobs = try driver. planBuild ( )
669+ XCTAssertEqual ( getFileListElements ( for: " -output-filelist " , job: jobs [ 0 ] ) ,
670+ [ . absolute( . init( " /tmp/build1/second.o " ) ) ] )
671+ XCTAssertEqual ( getFileListElements ( for: " -index-unit-output-path-filelist " , job: jobs [ 0 ] ) ,
672+ [ . absolute( . init( " /tmp/build2/second.o " ) ) ] )
673+ XCTAssertEqual ( getFileListElements ( for: " -output-filelist " , job: jobs [ 1 ] ) ,
674+ [ . absolute( . init( " /tmp/build1/main.o " ) ) ] )
675+ XCTAssertEqual ( getFileListElements ( for: " -index-unit-output-path-filelist " , job: jobs [ 1 ] ) ,
676+ [ . absolute( . init( " /tmp/build2/main.o " ) ) ] )
677+
678+
679+ // 2. Batch mode (two primary files)
680+ // a) without filelists
681+ driver = try Driver ( args: [
682+ " swiftc " , " -c " , " -enable-batch-mode " , " -driver-batch-count " , " 1 " ,
683+ " -output-file-map " , file. path. pathString,
684+ " -module-name " , " test " , " /tmp/second.swift " , " /tmp/main.swift "
685+ ] )
686+ jobs = try driver. planBuild ( )
687+ XCTAssertTrue ( jobs [ 0 ] . commandLine. contains ( subsequence: [ " -o " , . path( . absolute( . init( " /tmp/build1/second.o " ) ) ) ] ) )
688+ XCTAssertTrue ( jobs [ 0 ] . commandLine. contains ( subsequence: [ " -o " , . path( . absolute( . init( " /tmp/build1/main.o " ) ) ) ] ) )
689+ XCTAssertTrue ( jobs [ 0 ] . commandLine. contains ( subsequence: [ " -index-unit-output-path " , . path( . absolute( . init( " /tmp/build2/second.o " ) ) ) ] ) )
690+ XCTAssertTrue ( jobs [ 0 ] . commandLine. contains ( subsequence: [ " -index-unit-output-path " , . path( . absolute( . init( " /tmp/build2/main.o " ) ) ) ] ) )
691+
692+ // b) with filelists
693+ driver = try Driver ( args: [
694+ " swiftc " , " -c " , " -driver-filelist-threshold=0 " ,
695+ " -enable-batch-mode " , " -driver-batch-count " , " 1 " ,
696+ " -output-file-map " , file. path. pathString,
697+ " -module-name " , " test " , " /tmp/second.swift " , " /tmp/main.swift "
698+ ] )
699+ jobs = try driver. planBuild ( )
700+ XCTAssertEqual ( getFileListElements ( for: " -output-filelist " , job: jobs [ 0 ] ) ,
701+ [ . absolute( . init( " /tmp/build1/second.o " ) ) , . absolute( . init( " /tmp/build1/main.o " ) ) ] )
702+ XCTAssertEqual ( getFileListElements ( for: " -index-unit-output-path-filelist " , job: jobs [ 0 ] ) ,
703+ [ . absolute( . init( " /tmp/build2/second.o " ) ) , . absolute( . init( " /tmp/build2/main.o " ) ) ] )
704+
705+ // 3. Multi-threaded WMO
706+ // a) without filelists
707+ driver = try Driver ( args: [
708+ " swiftc " , " -c " , " -whole-module-optimization " , " -num-threads " , " 2 " ,
709+ " -output-file-map " , file. path. pathString,
710+ " -module-name " , " test " , " /tmp/second.swift " , " /tmp/main.swift "
711+ ] )
712+ jobs = try driver. planBuild ( )
713+ XCTAssertTrue ( jobs [ 0 ] . commandLine. contains ( subsequence: [ " -o " , . path( . absolute( . init( " /tmp/build1/second.o " ) ) ) ] ) )
714+ XCTAssertTrue ( jobs [ 0 ] . commandLine. contains ( subsequence: [ " -index-unit-output-path " , . path( . absolute( . init( " /tmp/build2/second.o " ) ) ) ] ) )
715+ XCTAssertTrue ( jobs [ 0 ] . commandLine. contains ( subsequence: [ " -o " , . path( . absolute( . init( " /tmp/build1/main.o " ) ) ) ] ) )
716+ XCTAssertTrue ( jobs [ 0 ] . commandLine. contains ( subsequence: [ " -index-unit-output-path " , . path( . absolute( . init( " /tmp/build2/main.o " ) ) ) ] ) )
717+
718+ // b) with filelists
719+ driver = try Driver ( args: [
720+ " swiftc " , " -c " , " -driver-filelist-threshold=0 " ,
721+ " -whole-module-optimization " , " -num-threads " , " 2 " ,
722+ " -output-file-map " , file. path. pathString,
723+ " -module-name " , " test " , " /tmp/second.swift " , " /tmp/main.swift "
724+ ] )
725+ jobs = try driver. planBuild ( )
726+ XCTAssertEqual ( getFileListElements ( for: " -output-filelist " , job: jobs [ 0 ] ) ,
727+ [ . absolute( . init( " /tmp/build1/second.o " ) ) , . absolute( . init( " /tmp/build1/main.o " ) ) ] )
728+ XCTAssertEqual ( getFileListElements ( for: " -index-unit-output-path-filelist " , job: jobs [ 0 ] ) ,
729+ [ . absolute( . init( " /tmp/build2/second.o " ) ) , . absolute( . init( " /tmp/build2/main.o " ) ) ] )
730+
731+ // 4. Index-file (single primary)
732+ driver = try Driver ( args: [
733+ " swiftc " , " -c " , " -enable-batch-mode " , " -driver-batch-count " , " 1 " ,
734+ " -module-name " , " test " , " /tmp/second.swift " , " /tmp/main.swift " ,
735+ " -index-file " , " -index-file-path " , " /tmp/second.swift " ,
736+ " -disable-batch-mode " , " -o " , " /tmp/build1/second.o " ,
737+ " -index-unit-output-path " , " /tmp/build2/second.o "
738+ ] )
739+ jobs = try driver. planBuild ( )
740+ XCTAssertTrue ( jobs [ 0 ] . commandLine. contains ( subsequence: [ " -o " , . path( . absolute( . init( " /tmp/build1/second.o " ) ) ) ] ) )
741+ XCTAssertTrue ( jobs [ 0 ] . commandLine. contains ( subsequence: [ " -index-unit-output-path " , . path( . absolute( . init( " /tmp/build2/second.o " ) ) ) ] ) )
742+ }
743+ }
744+ }
745+
617746 func testMergeModuleEmittingDependencies( ) throws {
618747 var driver1 = try Driver ( args: [ " swiftc " , " foo.swift " , " bar.swift " , " -module-name " , " Foo " , " -emit-dependencies " , " -emit-module " , " -serialize-diagnostics " , " -driver-filelist-threshold=9999 " ] )
619748 let plannedJobs = try driver1. planBuild ( ) . removingAutolinkExtractJobs ( )
0 commit comments