@@ -336,17 +336,38 @@ public struct Driver {
336
336
}
337
337
}
338
338
339
+ /// If PCH job is needed.
340
+ let producePCHJob : Bool
341
+
342
+ /// Original ObjC Header passed from command-line
343
+ let originalObjCHeaderFile : VirtualPath . Handle ?
344
+
339
345
/// The path to the imported Objective-C header.
340
- let importedObjCHeader : VirtualPath . Handle ?
346
+ lazy var importedObjCHeader : VirtualPath . Handle ? = {
347
+ assert ( explicitDependencyBuildPlanner != nil ||
348
+ !parsedOptions. hasArgument ( . driverExplicitModuleBuild) ||
349
+ !inputFiles. contains { $0. type == . swift } ,
350
+ " should not be queried before scanning " )
351
+ let chainedBridgingHeader = try ? explicitDependencyBuildPlanner? . getChainedBridgingHeaderFile ( )
352
+ return try ? computeImportedObjCHeader ( & parsedOptions, compilerMode: compilerMode,
353
+ chainedBridgingHeader: chainedBridgingHeader) ?? originalObjCHeaderFile
354
+ } ( )
355
+
356
+ /// The directory to emit PCH file.
357
+ lazy var bridgingPrecompiledHeaderOutputDir : VirtualPath ? = {
358
+ return try ? computePrecompiledBridgingHeaderDir ( & parsedOptions,
359
+ compilerMode: compilerMode)
360
+ } ( )
341
361
342
362
/// The path to the pch for the imported Objective-C header.
343
363
lazy var bridgingPrecompiledHeader : VirtualPath . Handle ? = {
344
364
let contextHash = try ? explicitDependencyBuildPlanner? . getMainModuleContextHash ( )
345
- return Self . computeBridgingPrecompiledHeader ( & parsedOptions,
346
- compilerMode: compilerMode,
347
- importedObjCHeader: importedObjCHeader,
348
- outputFileMap: outputFileMap,
349
- contextHash: contextHash)
365
+ return computeBridgingPrecompiledHeader ( & parsedOptions,
366
+ compilerMode: compilerMode,
367
+ importedObjCHeader: importedObjCHeader,
368
+ outputFileMap: outputFileMap,
369
+ outputDirectory: bridgingPrecompiledHeaderOutputDir,
370
+ contextHash: contextHash)
350
371
} ( )
351
372
352
373
/// Path to the dependencies file.
@@ -1053,8 +1074,6 @@ public struct Driver {
1053
1074
parsedOptions: parsedOptions,
1054
1075
recordedInputModificationDates: recordedInputModificationDates)
1055
1076
1056
- self . importedObjCHeader = try Self . computeImportedObjCHeader ( & parsedOptions, compilerMode: compilerMode, diagnosticEngine: diagnosticEngine)
1057
-
1058
1077
self . supportedFrontendFlags =
1059
1078
try Self . computeSupportedCompilerArgs ( of: self . toolchain,
1060
1079
libSwiftScan: self . swiftScanLibInstance,
@@ -1079,16 +1098,38 @@ public struct Driver {
1079
1098
diagnosticsEngine. emit ( . warning( " -cache-compile-job cannot be used without explicit module build, turn off caching " ) ,
1080
1099
location: nil )
1081
1100
self . enableCaching = false
1082
- } else if importedObjCHeader != nil , !parsedOptions. hasFlag ( positive: . enableBridgingPch, negative: . disableBridgingPch, default: true ) {
1083
- diagnosticsEngine. emit ( . warning( " -cache-compile-job cannot be used with -disable-bridging-pch, turn off caching " ) ,
1084
- location: nil )
1085
- self . enableCaching = false
1086
1101
} else {
1087
1102
self . enableCaching = true
1088
1103
}
1089
1104
} else {
1090
1105
self . enableCaching = false
1091
1106
}
1107
+
1108
+ // PCH related options.
1109
+ if parsedOptions. hasArgument ( . importObjcHeader) {
1110
+ // Check for conflicting options.
1111
+ if parsedOptions. hasArgument ( . importUnderlyingModule) {
1112
+ diagnosticEngine. emit ( . error_framework_bridging_header)
1113
+ }
1114
+
1115
+ if parsedOptions. hasArgument ( . emitModuleInterface, . emitModuleInterfacePath) {
1116
+ diagnosticEngine. emit ( . error_bridging_header_module_interface)
1117
+ }
1118
+ }
1119
+ var maybeNeedPCH = parsedOptions. hasFlag ( positive: . enableBridgingPch, negative: . disableBridgingPch, default: true )
1120
+ if enableCaching && !maybeNeedPCH {
1121
+ diagnosticsEngine. emit ( . warning( " -cache-compile-job cannot be used with -disable-bridging-pch, turn on PCH generation " ) ,
1122
+ location: nil )
1123
+ maybeNeedPCH = true
1124
+ }
1125
+ self . producePCHJob = maybeNeedPCH
1126
+
1127
+ if let objcHeaderPathArg = parsedOptions. getLastArgument ( . importObjcHeader) {
1128
+ self . originalObjCHeaderFile = try ? VirtualPath . intern ( path: objcHeaderPathArg. asSingle)
1129
+ } else {
1130
+ self . originalObjCHeaderFile = nil
1131
+ }
1132
+
1092
1133
self . useClangIncludeTree = !parsedOptions. hasArgument ( . noClangIncludeTree) && !env. keys. contains ( " SWIFT_CACHING_USE_CLANG_CAS_FS " )
1093
1134
self . scannerPrefixMap = try Self . computeScanningPrefixMapper ( & parsedOptions)
1094
1135
if let sdkMapping = parsedOptions. getLastArgument ( . scannerPrefixMapSdk) ? . asSingle {
@@ -3068,36 +3109,47 @@ extension Driver {
3068
3109
// Imported Objective-C header.
3069
3110
extension Driver {
3070
3111
/// Compute the path of the imported Objective-C header.
3071
- static func computeImportedObjCHeader(
3112
+ func computeImportedObjCHeader(
3072
3113
_ parsedOptions: inout ParsedOptions ,
3073
3114
compilerMode: CompilerMode ,
3074
- diagnosticEngine: DiagnosticsEngine
3075
- ) throws -> VirtualPath . Handle ? {
3076
- guard let objcHeaderPathArg = parsedOptions. getLastArgument ( . importObjcHeader) else {
3077
- return nil
3115
+ chainedBridgingHeader: ChainedBridgingHeaderFile ? ) throws -> VirtualPath . Handle ? {
3116
+ // handle chained bridging header.
3117
+ if let chainedHeader = chainedBridgingHeader, !chainedHeader. path. isEmpty {
3118
+ let path = try VirtualPath ( path: chainedHeader. path)
3119
+ let dirExists = try fileSystem. exists ( path. parentDirectory)
3120
+ if !dirExists, let dirToCreate = path. parentDirectory. absolutePath {
3121
+ try fileSystem. createDirectory ( dirToCreate, recursive: true )
3122
+ }
3123
+ try fileSystem. writeFileContents ( path,
3124
+ bytes: ByteString ( encodingAsUTF8: chainedHeader. content) ,
3125
+ atomically: true )
3126
+ return path. intern ( )
3078
3127
}
3128
+ return originalObjCHeaderFile
3129
+ }
3079
3130
3080
- // Check for conflicting options.
3081
- if parsedOptions. hasArgument ( . importUnderlyingModule) {
3082
- diagnosticEngine. emit ( . error_framework_bridging_header)
3131
+ /// Compute the path to the bridging precompiled header directory path.
3132
+ func computePrecompiledBridgingHeaderDir(
3133
+ _ parsedOptions: inout ParsedOptions ,
3134
+ compilerMode: CompilerMode ) throws -> VirtualPath ? {
3135
+ if let input = originalObjCHeaderFile,
3136
+ let outputPath = try ? outputFileMap? . existingOutput ( inputFile: input, outputType: . pch) {
3137
+ return VirtualPath . lookup ( outputPath) . parentDirectory
3083
3138
}
3084
-
3085
- if parsedOptions. hasArgument ( . emitModuleInterface, . emitModuleInterfacePath) {
3086
- diagnosticEngine. emit ( . error_bridging_header_module_interface)
3139
+ if let outputDir = parsedOptions. getLastArgument ( . pchOutputDir) ? . asSingle {
3140
+ return try VirtualPath ( path: outputDir)
3087
3141
}
3088
-
3089
- return try VirtualPath . intern ( path: objcHeaderPathArg. asSingle)
3142
+ return nil
3090
3143
}
3091
3144
3092
3145
/// Compute the path of the generated bridging PCH for the Objective-C header.
3093
- static func computeBridgingPrecompiledHeader( _ parsedOptions: inout ParsedOptions ,
3094
- compilerMode: CompilerMode ,
3095
- importedObjCHeader: VirtualPath . Handle ? ,
3096
- outputFileMap: OutputFileMap ? ,
3097
- contextHash: String ? ) -> VirtualPath . Handle ? {
3098
- guard compilerMode. supportsBridgingPCH,
3099
- let input = importedObjCHeader,
3100
- parsedOptions. hasFlag ( positive: . enableBridgingPch, negative: . disableBridgingPch, default: true ) else {
3146
+ func computeBridgingPrecompiledHeader( _ parsedOptions: inout ParsedOptions ,
3147
+ compilerMode: CompilerMode ,
3148
+ importedObjCHeader: VirtualPath . Handle ? ,
3149
+ outputFileMap: OutputFileMap ? ,
3150
+ outputDirectory: VirtualPath ? ,
3151
+ contextHash: String ? ) -> VirtualPath . Handle ? {
3152
+ guard compilerMode. supportsBridgingPCH, producePCHJob, let input = importedObjCHeader else {
3101
3153
return nil
3102
3154
}
3103
3155
@@ -3112,8 +3164,8 @@ extension Driver {
3112
3164
} else {
3113
3165
pchFile = baseName. appendingFileTypeExtension ( . pch)
3114
3166
}
3115
- if let outputDirectory = parsedOptions . getLastArgument ( . pchOutputDir ) ? . asSingle {
3116
- return try ? VirtualPath ( path : outputDirectory) . appending ( component: pchFile) . intern ( )
3167
+ if let outputDirectory = outputDirectory {
3168
+ return outputDirectory. appending ( component: pchFile) . intern ( )
3117
3169
} else {
3118
3170
return try ? VirtualPath . temporary ( RelativePath ( validating: pchFile) ) . intern ( )
3119
3171
}
0 commit comments