@@ -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
2629type 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
4343func (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.
4949func (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