Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit aa41179

Browse files
committed
DRAFT
1 parent e548e10 commit aa41179

File tree

3 files changed

+95
-15
lines changed

3 files changed

+95
-15
lines changed

‎internal/arduino/builder/internal/detector/cache.go‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121

2222
"github.com/arduino/arduino-cli/internal/arduino/builder/internal/runner"
2323
"github.com/arduino/go-paths-helper"
24+
"github.com/sirupsen/logrus"
2425
)
2526

2627
type detectorCache struct {
@@ -83,6 +84,15 @@ func (c *detectorCache) Load(cacheFile *paths.Path) error {
8384
if err := json.Unmarshal(data, &entries); err != nil {
8485
return err
8586
}
87+
// Check for invalid entries (stale files from previous Arduino CLI versions)
88+
for _, entry := range entries {
89+
if entry == nil {
90+
return nil
91+
}
92+
if entry.Compile != nil && entry.CompileTask == nil {
93+
return nil
94+
}
95+
}
8696
c.curr = 0
8797
c.entries = entries
8898
return nil
@@ -91,11 +101,14 @@ func (c *detectorCache) Load(cacheFile *paths.Path) error {
91101
// Expect adds an entry to the cache and checks if it matches the next expected entry.
92102
func (c *detectorCache) Expect(entry *detectorCacheEntry) {
93103
if c.curr < len(c.entries) {
104+
logrus.Debugf("Expecting cache entry: %s", entry)
94105
if c.entries[c.curr].Equals(entry) {
95106
// Cache hit, move to the next entry
96107
c.curr++
108+
logrus.Debugf(" CACHE HIT!")
97109
return
98110
}
111+
logrus.Debugf(" Cache MISMATCH!")
99112
// Cache mismatch, invalidate and cut the remainder of the cache
100113
c.entries = c.entries[:c.curr]
101114
}

‎internal/arduino/builder/internal/detector/detector.go‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
"github.com/arduino/arduino-cli/internal/i18n"
4242
"github.com/arduino/go-paths-helper"
4343
"github.com/arduino/go-properties-orderedmap"
44+
"github.com/sirupsen/logrus"
4445
)
4546

4647
type libraryResolutionResult struct {
@@ -273,14 +274,18 @@ func (l *SketchLibrariesDetector) findIncludes(
273274
l.preRunner = runner.New(ctx, jobs)
274275
for _, entry := range l.cache.EntriesAhead() {
275276
if entry.Compile != nil && entry.CompileTask != nil {
276-
upToDate, _ := entry.Compile.ObjFileIsUpToDate()
277+
upToDate, _ := entry.Compile.ObjFileIsUpToDate(logrus.WithField("source_file", entry.Compile.SourcePath))
277278
if !upToDate {
279+
_ = entry.Compile.PrepareBuildPath()
278280
l.preRunner.Enqueue(entry.CompileTask)
279281
}
280282
}
281283
}
282284
defer l.preRunner.Cancel()
283285

286+
time.Sleep(time.Second * 2)
287+
fmt.Println("----")
288+
284289
l.addIncludeFolder(buildCorePath)
285290
if buildVariantPath != nil {
286291
l.addIncludeFolder(buildVariantPath)
@@ -355,12 +360,15 @@ func (l *SketchLibrariesDetector) gccPreprocessTask(sourceFile *sourceFile, buil
355360
// search path, but only for the source code of the library, so we temporary
356361
// copy the current search path list and add the library' utility directory
357362
// if needed.
358-
includeFolders := l.includeFolders
363+
includeFolders := l.includeFolders.Clone()
359364
if extraInclude := sourceFile.ExtraIncludePath; extraInclude != nil {
360365
includeFolders = append(includeFolders, extraInclude)
361366
}
362367

363-
return preprocessor.GCC(sourceFile.SourcePath, paths.NullPath(), includeFolders, buildProperties)
368+
_ = sourceFile.PrepareBuildPath()
369+
task := preprocessor.GCC(sourceFile.SourcePath, paths.NullPath(), includeFolders, buildProperties)
370+
task.Args = append(task.Args, "-MMD", "-MF", sourceFile.DepfilePath.String())
371+
return task
364372
}
365373

366374
func (l *SketchLibrariesDetector) findMissingIncludesInCompilationUnit(
@@ -385,7 +393,7 @@ func (l *SketchLibrariesDetector) findMissingIncludesInCompilationUnit(
385393
// TODO: This reads the dependency file, but the actual building
386394
// does it again. Should the result be somehow cached? Perhaps
387395
// remove the object file if it is found to be stale?
388-
unchanged, err := sourceFile.ObjFileIsUpToDate()
396+
unchanged, err := sourceFile.ObjFileIsUpToDate(logrus.WithField("source_file", sourcePath))
389397
if err != nil {
390398
return err
391399
}
@@ -533,8 +541,7 @@ func (l *SketchLibrariesDetector) makeSourceFile(sourceRoot, buildRoot, sourceFi
533541
}
534542
res := &sourceFile{
535543
SourcePath: sourceRoot.JoinPath(sourceFilePath),
536-
ObjectPath: buildRoot.Join(sourceFilePath.String() + ".o"),
537-
DepfilePath: buildRoot.Join(sourceFilePath.String() + ".d"),
544+
DepfilePath: buildRoot.Join(fmt.Sprintf("%s.libsdetect.d", sourceFilePath)),
538545
ExtraIncludePath: extraIncludePath,
539546
}
540547
return res, nil

‎internal/arduino/builder/internal/detector/source_file.go‎

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@ import (
1919
"fmt"
2020
"slices"
2121

22-
"github.com/arduino/arduino-cli/internal/arduino/builder/internal/utils"
22+
"os"
23+
24+
"github.com/arduino/arduino-cli/internal/arduino/builder/cpp"
2325
"github.com/arduino/go-paths-helper"
26+
"github.com/sirupsen/logrus"
2427
)
2528

2629
type sourceFile struct {
2730
// SourcePath is the path to the source file
2831
SourcePath *paths.Path `json:"source_path"`
2932

30-
// ObjectPath is the path to the object file that will be generated
31-
ObjectPath *paths.Path `json:"object_path"`
32-
3333
// DepfilePath is the path to the dependency file that will be generated
3434
DepfilePath *paths.Path `json:"depfile_path"`
3535

@@ -41,22 +41,82 @@ type sourceFile struct {
4141
}
4242

4343
func (f *sourceFile) String() string {
44-
return fmt.Sprintf("SourcePath:%s SourceRoot:%s BuildRoot:%s ExtraInclude:%s",
45-
f.SourcePath, f.ObjectPath, f.DepfilePath, f.ExtraIncludePath)
44+
return fmt.Sprintf("%s -> dep:%s (ExtraInclude:%s)",
45+
f.SourcePath, f.DepfilePath, f.ExtraIncludePath)
4646
}
4747

4848
// Equals checks if a sourceFile is equal to another.
4949
func (f *sourceFile) Equals(g *sourceFile) bool {
5050
return f.SourcePath.EqualsTo(g.SourcePath) &&
51-
f.ObjectPath.EqualsTo(g.ObjectPath) &&
5251
f.DepfilePath.EqualsTo(g.DepfilePath) &&
5352
((f.ExtraIncludePath == nil && g.ExtraIncludePath == nil) ||
5453
(f.ExtraIncludePath != nil && g.ExtraIncludePath != nil && f.ExtraIncludePath.EqualsTo(g.ExtraIncludePath)))
5554
}
5655

56+
// PrepareBuildPath ensures that the directory for the dependency file exists.
57+
func (f *sourceFile) PrepareBuildPath() error {
58+
if f.DepfilePath != nil {
59+
return f.DepfilePath.Parent().MkdirAll()
60+
}
61+
return nil
62+
}
63+
5764
// ObjFileIsUpToDate checks if the compile object file is up to date.
58-
func (f *sourceFile) ObjFileIsUpToDate() (unchanged bool, err error) {
59-
return utils.ObjFileIsUpToDate(f.SourcePath, f.ObjectPath, f.DepfilePath)
65+
func (f *sourceFile) ObjFileIsUpToDate(log *logrus.Entry) (unchanged bool, err error) {
66+
log.Debugf("Checking previous results for %v (dep = %v)", f.SourcePath, f.DepfilePath)
67+
if f.DepfilePath == nil {
68+
log.Debugf(" Object file or dependency file not provided")
69+
return false, nil
70+
}
71+
72+
sourceFile := f.SourcePath.Clean()
73+
sourceFileStat, err := sourceFile.Stat()
74+
if err != nil {
75+
log.Debugf(" Could not stat source file: %s", err)
76+
return false, err
77+
}
78+
dependencyFile := f.DepfilePath.Clean()
79+
dependencyFileStat, err := dependencyFile.Stat()
80+
if err != nil {
81+
if os.IsNotExist(err) {
82+
log.Debugf(" Dependency file not found: %v", dependencyFile)
83+
return false, nil
84+
}
85+
log.Debugf(" Could not stat dependency file: %s", err)
86+
return false, err
87+
}
88+
if sourceFileStat.ModTime().After(dependencyFileStat.ModTime()) {
89+
log.Debugf(" %v newer than %v", sourceFile, dependencyFile)
90+
return false, nil
91+
}
92+
deps, err := cpp.ReadDepFile(dependencyFile)
93+
if err != nil {
94+
log.Debugf(" Could not read dependency file: %s", dependencyFile)
95+
return false, err
96+
}
97+
if len(deps.Dependencies) == 0 {
98+
return true, nil
99+
}
100+
if deps.Dependencies[0] != sourceFile.String() {
101+
log.Debugf(" Depfile is about different source file: %v (expected %v)", deps.Dependencies[0], sourceFile)
102+
return false, nil
103+
}
104+
for _, dep := range deps.Dependencies[1:] {
105+
depStat, err := os.Stat(dep)
106+
if os.IsNotExist(err) {
107+
log.Debugf(" Not found: %v", dep)
108+
return false, nil
109+
}
110+
if err != nil {
111+
logrus.WithError(err).Debugf(" Failed to read: %v", dep)
112+
return false, nil
113+
}
114+
if depStat.ModTime().After(dependencyFileStat.ModTime()) {
115+
log.Debugf(" %v newer than %v", dep, dependencyFile)
116+
return false, nil
117+
}
118+
}
119+
return true, nil
60120
}
61121

62122
// uniqueSourceFileQueue is a queue of source files that does not allow duplicates.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /