Skip to content

Commit 1c57270

Browse files
committed
Fixed ObjFileIsUptodate checks in library discovery.
During the library detection phase, we do not have objects files yet, the only thing that we should check is if the dependency file is up-to-date. In this commit we let GCC create a dep file during the library discovery phase. We must ensure that the build-path folder exists otherwise the compiler will not be able to create the dep file.
1 parent 35ec6f8 commit 1c57270

File tree

2 files changed

+72
-11
lines changed

2 files changed

+72
-11
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ func (l *SketchLibrariesDetector) findIncludes(
275275
if entry.Compile != nil && entry.CompileTask != nil {
276276
upToDate, _ := entry.Compile.ObjFileIsUpToDate()
277277
if !upToDate {
278+
_ = entry.Compile.PrepareBuildPath()
278279
l.preRunner.Enqueue(entry.CompileTask)
279280
}
280281
}
@@ -360,7 +361,8 @@ func (l *SketchLibrariesDetector) gccPreprocessTask(sourceFile *sourceFile, buil
360361
includeFolders = append(includeFolders, extraInclude)
361362
}
362363

363-
return preprocessor.GCC(sourceFile.SourcePath, paths.NullPath(), includeFolders, buildProperties, nil)
364+
_ = sourceFile.PrepareBuildPath()
365+
return preprocessor.GCC(sourceFile.SourcePath, paths.NullPath(), includeFolders, buildProperties, sourceFile.DepfilePath)
364366
}
365367

366368
func (l *SketchLibrariesDetector) findMissingIncludesInCompilationUnit(
@@ -533,8 +535,7 @@ func (l *SketchLibrariesDetector) makeSourceFile(sourceRoot, buildRoot, sourceFi
533535
}
534536
res := &sourceFile{
535537
SourcePath: sourceRoot.JoinPath(sourceFilePath),
536-
ObjectPath: buildRoot.Join(sourceFilePath.String() + ".o"),
537-
DepfilePath: buildRoot.Join(sourceFilePath.String() + ".d"),
538+
DepfilePath: buildRoot.Join(fmt.Sprintf("%s.libsdetect.d", sourceFilePath)),
538539
ExtraIncludePath: extraIncludePath,
539540
}
540541
return res, nil

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

Lines changed: 68 additions & 8 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.
5865
func (f *sourceFile) ObjFileIsUpToDate() (unchanged bool, err error) {
59-
return utils.ObjFileIsUpToDate(f.SourcePath, f.ObjectPath, f.DepfilePath)
66+
logrus.Debugf("Checking previous results for %v (dep = %v)", f.SourcePath, f.DepfilePath)
67+
if f.DepfilePath == nil {
68+
logrus.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+
logrus.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+
logrus.Debugf(" Dependency file not found: %v", dependencyFile)
83+
return false, nil
84+
}
85+
logrus.Debugf(" Could not stat dependency file: %s", err)
86+
return false, err
87+
}
88+
if sourceFileStat.ModTime().After(dependencyFileStat.ModTime()) {
89+
logrus.Debugf(" %v newer than %v", sourceFile, dependencyFile)
90+
return false, nil
91+
}
92+
deps, err := cpp.ReadDepFile(dependencyFile)
93+
if err != nil {
94+
logrus.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+
logrus.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+
logrus.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+
logrus.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)