@@ -5041,4 +5041,106 @@ fileprivate struct SwiftDriverTests: CoreBasedTests {
50415041 }
50425042 }
50435043 }
5044+
5045+ @Test ( . requireSDKs( . macOS) )
5046+ func incrementalExplicitModulesLinkerSwiftmoduleRegistration( ) async throws {
5047+ try await withTemporaryDirectory { tmpDirPath async throws -> Void in
5048+ let testWorkspace = try await TestWorkspace (
5049+ " Test " ,
5050+ sourceRoot: tmpDirPath. join ( " Test " ) ,
5051+ projects: [
5052+ TestProject (
5053+ " aProject " ,
5054+ groupTree: TestGroup (
5055+ " Sources " ,
5056+ path: " Sources " ,
5057+ children: [
5058+ TestFile ( " fileA1.swift " ) ,
5059+ ] ) ,
5060+ buildConfigurations: [
5061+ TestBuildConfiguration (
5062+ " Debug " ,
5063+ buildSettings: [
5064+ " PRODUCT_NAME " : " $(TARGET_NAME) " ,
5065+ " SWIFT_VERSION " : swiftVersion,
5066+ " BUILD_VARIANTS " : " normal " ,
5067+ " SWIFT_USE_INTEGRATED_DRIVER " : " YES " ,
5068+ " SWIFT_ENABLE_EXPLICIT_MODULES " : " YES " ,
5069+ ] )
5070+ ] ,
5071+ targets: [
5072+ TestStandardTarget (
5073+ " TargetA " ,
5074+ type: . framework,
5075+ buildPhases: [
5076+ TestSourcesBuildPhase ( [
5077+ " fileA1.swift " ,
5078+ ] ) ,
5079+ ] ) ,
5080+ ] )
5081+ ] )
5082+
5083+ let tester = try await BuildOperationTester ( getCore ( ) , testWorkspace, simulated: false )
5084+ tester. userInfo = tester. userInfo. withAdditionalEnvironment ( environment: [ " SWIFT_FORCE_MODULE_LOADING " : " only-interface " ] )
5085+ let parameters = BuildParameters ( configuration: " Debug " , overrides: [
5086+ // Redirect the prebuilt cache so we always build modules from source
5087+ " SWIFT_OVERLOAD_PREBUILT_MODULE_CACHE_PATH " : tmpDirPath. str
5088+ ] )
5089+ let buildRequest = BuildRequest ( parameters: parameters, buildTargets: tester. workspace. projects [ 0 ] . targets. map ( { BuildRequest . BuildTargetInfo ( parameters: parameters, target: $0) } ) , continueBuildingAfterErrors: false , useParallelTargets: true , useImplicitDependencies: false , useDryRun: false )
5090+ let SRCROOT = testWorkspace. sourceRoot. join ( " aProject " )
5091+
5092+ // Create the source files.
5093+ try await tester. fs. writeFileContents ( SRCROOT . join ( " Sources/fileA1.swift " ) ) { file in
5094+ file <<<
5095+ """
5096+ public struct A {
5097+ public init() { }
5098+ }
5099+ """
5100+ }
5101+
5102+ var cleanResponseFileContents : ByteString ? = nil
5103+ try await tester. checkBuild ( runDestination: . macOS, buildRequest: buildRequest, persistent: true ) { results in
5104+ var responseFile : Path ? = nil
5105+ results. checkTask ( . matchRuleType( " SwiftDriver Compilation Requirements " ) ) { driverTask in
5106+ responseFile = driverTask. outputPaths. filter { $0. str. hasSuffix ( " -linker-args.resp " ) } . only
5107+ }
5108+ try results. checkTask ( . matchRuleType( " Ld " ) ) { linkTask in
5109+ linkTask. checkCommandLineContains ( " @ \( try #require( responseFile) . str) " )
5110+ }
5111+ let responseFileContents = try tester. fs. read ( try #require( responseFile) )
5112+ #expect( !responseFileContents. isEmpty)
5113+ cleanResponseFileContents = responseFileContents
5114+ }
5115+
5116+ try await tester. fs. writeFileContents ( SRCROOT . join ( " Sources/fileA1.swift " ) ) { file in
5117+ file <<<
5118+ """
5119+ public struct A {
5120+ public init() { }
5121+ }
5122+
5123+ public func foo() { }
5124+ """
5125+ }
5126+
5127+ var incrementalResponseFileContents : ByteString ? = nil
5128+ try await tester. checkBuild ( runDestination: . macOS, buildRequest: buildRequest, persistent: true ) { results in
5129+ var responseFile : Path ? = nil
5130+ results. checkTask ( . matchRuleType( " SwiftDriver Compilation Requirements " ) ) { driverTask in
5131+ responseFile = driverTask. outputPaths. filter { $0. str. hasSuffix ( " -linker-args.resp " ) } . only
5132+ }
5133+ try results. checkTask ( . matchRuleType( " Ld " ) ) { linkTask in
5134+ linkTask. checkCommandLineContains ( " @ \( try #require( responseFile) . str) " )
5135+ }
5136+ let responseFileContents = try tester. fs. read ( try #require( responseFile) )
5137+ #expect( !responseFileContents. isEmpty)
5138+ incrementalResponseFileContents = responseFileContents
5139+ }
5140+
5141+ let cleanContents = try #require( cleanResponseFileContents)
5142+ let incrementalContents = try #require( incrementalResponseFileContents)
5143+ #expect( cleanContents == incrementalContents)
5144+ }
5145+ }
50445146}
0 commit comments