@@ -5041,4 +5041,106 @@ fileprivate struct SwiftDriverTests: CoreBasedTests {
5041
5041
}
5042
5042
}
5043
5043
}
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
+ }
5044
5146
}
0 commit comments