@@ -59,6 +59,7 @@ type SketchLibrariesDetector struct {
5959 includeFolders paths.PathList
6060 logger * logger.BuilderLogger
6161 diagnosticStore * diagnostics.Store
62+ preRunner * runner.Runner
6263}
6364
6465// NewSketchLibrariesDetector todo
@@ -254,6 +255,18 @@ func (l *SketchLibrariesDetector) findIncludes(
254255 l .logger .Warn (i18n .Tr ("Failed to load library discovery cache: %[1]s" , err ))
255256 }
256257
258+ // Pre-run cache entries
259+ l .preRunner = runner .New (ctx )
260+ for _ , entry := range l .cache .EntriesAhead () {
261+ if entry .Compile != nil && entry .CompileTask != nil {
262+ upToDate , _ := entry .Compile .ObjFileIsUpToDate ()
263+ if ! upToDate {
264+ l .preRunner .Enqueue (entry .CompileTask )
265+ }
266+ }
267+ }
268+ defer l .preRunner .Cancel ()
269+
257270 l .addIncludeFolder (buildCorePath )
258271 if buildVariantPath != nil {
259272 l .addIncludeFolder (buildVariantPath )
@@ -291,6 +304,15 @@ func (l *SketchLibrariesDetector) findIncludes(
291304 cachePath .Remove ()
292305 return err
293306 }
307+
308+ // Create a new pre-runner if the previous one was cancelled
309+ if l .preRunner == nil {
310+ l .preRunner = runner .New (ctx )
311+ // Push in the remainder of the queue
312+ for _ , sourceFile := range * sourceFileQueue {
313+ l .preRunner .Enqueue (l .gccPreprocessTask (sourceFile , buildProperties ))
314+ }
315+ }
294316 }
295317
296318 // Finalize the cache
@@ -354,9 +376,9 @@ func (l *SketchLibrariesDetector) findMissingIncludesInCompilationUnit(
354376
355377 first := true
356378 for {
357- l .cache .Expect (& detectorCacheEntry {Compile : sourceFile })
358-
359379 preprocTask := l .gccPreprocessTask (sourceFile , buildProperties )
380+ l .cache .Expect (& detectorCacheEntry {Compile : sourceFile , CompileTask : preprocTask })
381+
360382 var preprocErr error
361383 var preprocResult * runner.Result
362384
@@ -368,8 +390,27 @@ func (l *SketchLibrariesDetector) findMissingIncludesInCompilationUnit(
368390 }
369391 first = false
370392 } else {
371- preprocResult = preprocTask .Run (ctx )
372- preprocErr = preprocResult .Error
393+ if l .preRunner != nil {
394+ if r := l .preRunner .Results (preprocTask ); r != nil {
395+ preprocResult = r
396+ preprocErr = preprocResult .Error
397+ }
398+ }
399+ if preprocResult == nil {
400+ // The pre-runner missed this task, maybe the cache is outdated
401+ // or maybe the source code changed.
402+
403+ // Stop the pre-runner
404+ if l .preRunner != nil {
405+ preRunner := l .preRunner
406+ l .preRunner = nil
407+ go preRunner .Cancel ()
408+ }
409+
410+ // Run the actual preprocessor
411+ preprocResult = preprocTask .Run (ctx )
412+ preprocErr = preprocResult .Error
413+ }
373414 if l .logger .VerbosityLevel () == logger .VerbosityVerbose {
374415 l .logger .WriteStdout (preprocResult .Stdout )
375416 }
0 commit comments