@@ -1611,17 +1611,24 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible
16111611 let ( precompFile, pchInfoAny) = delegate. createOrReuseSharedNodeWithIdentifier ( sharingIdentString) { ( ) -> ( any PlannedNode , any Sendable ) in
16121612 // This block is invoked only when we need to create a task to precompile a header.
16131613
1614+ // Ordering gate: a workspace level task will wire together all sharing targets' startCompilingNode.
1615+ let orderingNode = delegate. createVirtualNode ( " shared-pch-ordering- \( sharingIdentHashValue) " )
1616+
16141617 // Construct the full path of the precomp file, which includes the hash to make it unique.
16151618 // FIXME: This needs to actually include a hash code, and it should ideally (for comparison reasons) be the same as Xcode.
16161619 let precompPath = baseCachePath. join ( " SharedPrecompiledHeaders " ) . join ( " \( sharingIdentHashValue) " ) . join ( prefixHeader. basename + " .gch " )
16171620
16181621 // Start by invoking our logic to create a task to precompile the prefix header.
1619- let pchInfo = self . precompile ( cbc, delegate, headerPath: prefixHeader, language: language, inputFileType: inputFileType, extraArgs: perFileFlags, precompPath: precompPath, clangInfo: clangInfo)
1622+ let pchInfo = self . precompile ( cbc, delegate, headerPath: prefixHeader, language: language, inputFileType: inputFileType, extraArgs: perFileFlags, precompPath: precompPath, clangInfo: clangInfo, additionalOrderingInputs : [ orderingNode ] )
16201623
16211624 // Return the output node for the precomp file.
16221625 return ( delegate. createNode ( precompPath) , pchInfo)
16231626 }
16241627
1628+ // Ensure shared ProcessPCH depends on all consuming targets upstream headers.
1629+ let orderingNode = delegate. createVirtualNode ( " shared-pch-ordering- \( sharingIdentHashValue) " )
1630+ delegate. registerSharedPCHOrderingDependency ( sharingIdentString, orderingNode: orderingNode)
1631+
16251632 let pchInfo = pchInfoAny as! ClangPrefixInfo . PCHInfo
16261633
16271634 // Include the precomp file.
@@ -1659,7 +1666,7 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible
16591666 }
16601667
16611668 /// Specialized function that creates a task for precompiling a particular header.
1662- private func precompile( _ cbc: CommandBuildContext , _ delegate: any TaskGenerationDelegate , headerPath: Path , language: GCCCompatibleLanguageDialect , inputFileType: FileTypeSpec , extraArgs: [ String ] , precompPath: Path , clangInfo: DiscoveredClangToolSpecInfo ? ) -> ClangPrefixInfo . PCHInfo {
1669+ private func precompile( _ cbc: CommandBuildContext , _ delegate: any TaskGenerationDelegate , headerPath: Path , language: GCCCompatibleLanguageDialect , inputFileType: FileTypeSpec , extraArgs: [ String ] , precompPath: Path , clangInfo: DiscoveredClangToolSpecInfo ? , additionalOrderingInputs : [ any PlannedNode ] = [ ] ) -> ClangPrefixInfo . PCHInfo {
16631670
16641671 // FIXME: Disabled for now because some projects manages to end up getting here with multiple files. <rdar://problem/23682348> Project groups multiple .c files together for C compiler?
16651672 //let input = cbc.input
@@ -1773,7 +1780,8 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible
17731780 // If explicit modules are enabled we need to create the scan task first
17741781 let extraInputs : [ Path ]
17751782 if action != nil {
1776- delegate. createTask ( type: self , payload: payload, ruleInfo: [ " ScanDependencies " ] + ruleInfo. dropFirst ( ) , additionalSignatureData: additionalSignatureData, commandLine: [ " builtin-ScanDependencies " , " -o " , scanningOutput. str, " -- " ] + commandLine, additionalOutput: responseFileAdditionalOutput, environment: environmentBindings, workingDirectory: compilerWorkingDirectory ( cbc) , inputs: inputPaths, outputs: [ scanningOutput] , action: delegate. taskActionCreationDelegate. createClangScanTaskAction ( ) , execDescription: " Scan dependencies of \( headerPath. basename) " , preparesForIndexing: true , enableSandboxing: enableSandboxing, additionalTaskOrderingOptions: [ . compilationForIndexableSourceFile] , usesExecutionInputs: usesExecutionInputs)
1783+ let scanInputNodes : [ any PlannedNode ] = inputPaths. map ( delegate. createNode) + additionalOrderingInputs
1784+ delegate. createTask ( type: self , payload: payload, ruleInfo: [ " ScanDependencies " ] + ruleInfo. dropFirst ( ) , additionalSignatureData: additionalSignatureData, commandLine: [ " builtin-ScanDependencies " , " -o " , scanningOutput. str, " -- " ] + commandLine, additionalOutput: responseFileAdditionalOutput, environment: environmentBindings, workingDirectory: compilerWorkingDirectory ( cbc) , inputs: scanInputNodes, outputs: [ delegate. createNode ( scanningOutput) ] , action: delegate. taskActionCreationDelegate. createClangScanTaskAction ( ) , execDescription: " Scan dependencies of \( headerPath. basename) " , preparesForIndexing: true , enableSandboxing: enableSandboxing, additionalTaskOrderingOptions: [ . compilationForIndexableSourceFile] , usesExecutionInputs: usesExecutionInputs)
17771785
17781786 extraInputs = [ scanningOutput]
17791787 } else {
@@ -1782,7 +1790,8 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible
17821790
17831791 // Finally, create the task.
17841792 let execDescription = archSpecificExecutionDescription ( cbc. scope. namespace. parseString ( " Precompile \( headerPath. basename) " ) , cbc, delegate)
1785- delegate. createTask ( type: self , dependencyData: dependencyData, payload: payload, ruleInfo: ruleInfo, additionalSignatureData: additionalSignatureData, commandLine: byteStringCommandLine, additionalOutput: additionalOutput, environment: environmentBindings, workingDirectory: compilerWorkingDirectory ( cbc) , inputs: inputPaths + extraInputs, outputs: outputPaths, action: action ?? delegate. taskActionCreationDelegate. createDeferredExecutionTaskActionIfRequested ( userPreferences: cbc. producer. userPreferences) , execDescription: execDescription, enableSandboxing: enableSandboxing, usesExecutionInputs: usesExecutionInputs, showEnvironment: true )
1793+ let allInputNodes : [ any PlannedNode ] = ( inputPaths + extraInputs) . map ( delegate. createNode) + additionalOrderingInputs
1794+ delegate. createTask ( type: self , dependencyData: dependencyData, payload: payload, ruleInfo: ruleInfo, additionalSignatureData: additionalSignatureData, commandLine: byteStringCommandLine, additionalOutput: additionalOutput, environment: environmentBindings, workingDirectory: compilerWorkingDirectory ( cbc) , inputs: allInputNodes, outputs: outputPaths. map ( delegate. createNode) , mustPrecede: [ ] , action: action ?? delegate. taskActionCreationDelegate. createDeferredExecutionTaskActionIfRequested ( userPreferences: cbc. producer. userPreferences) , execDescription: execDescription, preparesForIndexing: false , enableSandboxing: enableSandboxing, llbuildControlDisabled: false , additionalTaskOrderingOptions: [ ] , usesExecutionInputs: usesExecutionInputs, showEnvironment: true )
17861795
17871796 // If the object file verifier is enabled and we are building with explicit modules, also create a job to produce an adjacent PCH using implicit modules.
17881797 if cbc. scope. evaluate ( BuiltinMacros . CLANG_ENABLE_EXPLICIT_MODULES_OBJECT_FILE_VERIFIER) && action != nil {
0 commit comments