@@ -271,6 +271,14 @@ def allSectionsLocked(repository):
271271 section .lock .release ()
272272
273273
274+ def readPchHash (pchFile ):
275+ with open (pchFile + ".clcache" , 'r' ) as f :
276+ return f .read ()
277+
278+ def writePchHash (pchFile , hashSum ):
279+ with open (pchFile + ".clcache" , 'w' ) as f :
280+ f .write ('{}' .format (hashSum ))
281+
274282class ManifestRepository :
275283 # Bump this counter whenever the current manifest file format changes.
276284 # E.g. changing the file format from {'oldkey': ...} to {'newkey': ...} requires
@@ -333,6 +341,10 @@ def getManifestHash(compilerBinary, commandLine, sourceFile):
333341
334342 additionalData = "{}|{}|{}" .format (
335343 compilerHash , commandLine , ManifestRepository .MANIFEST_FILE_FORMAT_VERSION )
344+
345+ if 'Yu' in arguments :
346+ pchFile = CommandLineAnalyzer .getPchFileName (arguments , sourceFile )
347+ additionalData += readPchHash (pchFile )
336348 return getFileHash (sourceFile , additionalData )
337349
338350 @staticmethod
@@ -1308,6 +1320,20 @@ def parseArgumentsAndInputFiles(cmdline):
13081320
13091321 return dict (arguments ), inputFiles
13101322
1323+ @staticmethod
1324+ def getPchFileName (options , inputFile ):
1325+ if 'Fp' in options :
1326+ return options ['Fp' ][0 ]
1327+ if 'Yc' in options :
1328+ pchName = options ['Yc' ][0 ]
1329+ elif 'Yu' in options :
1330+ pchName = options ['Yu' ][0 ]
1331+ else :
1332+ return None
1333+ if not pchName :
1334+ pchName = inputFile
1335+ return basenameWithoutExtension (pchName ) + '.pch'
1336+
13111337 @staticmethod
13121338 def analyze (cmdline : List [str ]) -> Tuple [List [Tuple [str , str ]], List [str ]]:
13131339 options , inputFiles = CommandLineAnalyzer .parseArgumentsAndInputFiles (cmdline )
@@ -1336,9 +1362,6 @@ def analyze(cmdline: List[str]) -> Tuple[List[Tuple[str, str]], List[str]]:
13361362 if 'Zi' in options :
13371363 raise ExternalDebugInfoError ()
13381364
1339- if 'Yc' in options or 'Yu' in options :
1340- raise CalledWithPchError ()
1341-
13421365 if 'link' in options or 'c' not in options :
13431366 raise CalledForLinkError ()
13441367
@@ -1358,6 +1381,11 @@ def analyze(cmdline: List[str]) -> Tuple[List[Tuple[str, str]], List[str]]:
13581381 # Generate from .c/.cpp filenames
13591382 objectFiles = [os .path .join (prefix , basenameWithoutExtension (f )) + '.obj' for f , _ in inputFiles ]
13601383
1384+ if 'Yc' in options :
1385+ assert len (objectFiles ) == 1
1386+ pchFile = CommandLineAnalyzer .getPchFileName (options , inputFiles [0 ][0 ])
1387+ objectFiles = [(objectFiles [0 ], pchFile )]
1388+
13611389 printTraceStatement ("Compiler source files: {}" .format (inputFiles ))
13621390 printTraceStatement ("Compiler object file: {}" .format (objectFiles ))
13631391 return inputFiles , objectFiles
@@ -1531,6 +1559,7 @@ def addObjectToCache(stats, cache, cachekey, artifacts):
15311559
15321560def processCacheHit (cache , objectFile , cachekey ):
15331561 printTraceStatement ("Reusing cached object for key {} for object file {}" .format (cachekey , objectFile ))
1562+ objectFile , pchFile = objectFile if isinstance (objectFile , tuple ) else (objectFile , None )
15341563
15351564 with cache .lockFor (cachekey ):
15361565 with cache .statistics .lock , cache .statistics as stats :
@@ -1541,6 +1570,11 @@ def processCacheHit(cache, objectFile, cachekey):
15411570
15421571 cachedArtifacts = cache .getEntry (cachekey )
15431572 copyOrLink (cachedArtifacts .objectFilePath , objectFile )
1573+ if pchFile is not None :
1574+ pchCachedArtifacts = cache .getEntry (cachekey + "-pch" )
1575+ copyOrLink (pchCachedArtifacts .objectFilePath , pchFile )
1576+ writePchHash (pchFile , cachekey )
1577+
15441578 printTraceStatement ("Finished. Exit code 0" )
15451579 return 0 , cachedArtifacts .stdout , cachedArtifacts .stderr , False
15461580
@@ -1804,6 +1838,8 @@ def processNoDirect(cache, objectFile, compiler, cmdLine, environment):
18041838def ensureArtifactsExist (cache , cachekey , reason , objectFile , compilerResult , extraCallable = None ):
18051839 cleanupRequired = False
18061840 returnCode , compilerOutput , compilerStderr = compilerResult
1841+ objectFile , pchFile = objectFile if isinstance (objectFile , tuple ) else (objectFile , None )
1842+
18071843 correctCompiliation = (returnCode == 0 and os .path .exists (objectFile ))
18081844 with cache .lockFor (cachekey ):
18091845 if not cache .hasEntry (cachekey ):
@@ -1814,6 +1850,17 @@ def ensureArtifactsExist(cache, cachekey, reason, objectFile, compilerResult, ex
18141850 cleanupRequired = addObjectToCache (stats , cache , cachekey , artifacts )
18151851 if extraCallable and correctCompiliation :
18161852 extraCallable ()
1853+
1854+ if pchFile :
1855+ writePchHash (pchFile , cachekey )
1856+ cachekey = cachekey + "-pch"
1857+ with cache .lockFor (cachekey ):
1858+ if not cache .hasEntry (cachekey ):
1859+ with cache .statistics .lock , cache .statistics as stats :
1860+ if correctCompiliation :
1861+ artifacts = CompilerArtifacts (pchFile , "" , "" )
1862+ cleanupRequired = addObjectToCache (stats , cache , cachekey , artifacts ) or cleanupRequired
1863+
18171864 return returnCode , compilerOutput , compilerStderr , cleanupRequired
18181865
18191866
0 commit comments