@@ -17,6 +17,7 @@ package utils
1717
1818import (
1919 "os"
20+ "runtime"
2021 "strings"
2122 "unicode"
2223
@@ -32,33 +33,36 @@ import (
3233func ObjFileIsUpToDate (sourceFile , objectFile , dependencyFile * paths.Path ) (bool , error ) {
3334 logrus .Debugf ("Checking previous results for %v (result = %v, dep = %v)" , sourceFile , objectFile , dependencyFile )
3435 if objectFile == nil || dependencyFile == nil {
35- logrus .Debugf ("Not found: nil " )
36+ logrus .Debugf ("Object file or dependency file not provided " )
3637 return false , nil
3738 }
3839
3940 sourceFile = sourceFile .Clean ()
4041 sourceFileStat , err := sourceFile .Stat ()
4142 if err != nil {
43+ logrus .Debugf ("Could not stat source file: %s" , err )
4244 return false , err
4345 }
4446
4547 objectFile = objectFile .Clean ()
4648 objectFileStat , err := objectFile .Stat ()
4749 if err != nil {
4850 if os .IsNotExist (err ) {
49- logrus .Debugf ("Not found: %v" , objectFile )
51+ logrus .Debugf ("Object file not found: %v" , objectFile )
5052 return false , nil
5153 }
54+ logrus .Debugf ("Could not stat object file: %s" , err )
5255 return false , err
5356 }
5457
5558 dependencyFile = dependencyFile .Clean ()
5659 dependencyFileStat , err := dependencyFile .Stat ()
5760 if err != nil {
5861 if os .IsNotExist (err ) {
59- logrus .Debugf ("Not found: %v" , dependencyFile )
62+ logrus .Debugf ("Dependency file not found: %v" , dependencyFile )
6063 return false , nil
6164 }
65+ logrus .Debugf ("Could not stat dependency file: %s" , err )
6266 return false , err
6367 }
6468
@@ -71,61 +75,79 @@ func ObjFileIsUpToDate(sourceFile, objectFile, dependencyFile *paths.Path) (bool
7175 return false , nil
7276 }
7377
74- rows , err := dependencyFile .ReadFileAsLines ()
78+ depFileData , err := dependencyFile .ReadFile ()
7579 if err != nil {
80+ logrus .Debugf ("Could not read dependency file: %s" , dependencyFile )
7681 return false , err
7782 }
7883
79- rows = f .Map (rows , removeEndingBackSlash )
80- rows = f .Map (rows , strings .TrimSpace )
81- rows = f .Map (rows , unescapeDep )
82- rows = f .Filter (rows , f .NotEquals ("" ))
84+ checkDepFile := func (depFile string ) (bool , error ) {
85+ rows := strings .Split (strings .Replace (depFile , "\r \n " , "\n " , - 1 ), "\n " )
86+ rows = f .Map (rows , removeEndingBackSlash )
87+ rows = f .Map (rows , strings .TrimSpace )
88+ rows = f .Map (rows , unescapeDep )
89+ rows = f .Filter (rows , f .NotEquals ("" ))
8390
84- if len (rows ) == 0 {
85- return true , nil
86- }
87-
88- firstRow := rows [0 ]
89- if ! strings .HasSuffix (firstRow , ":" ) {
90- logrus .Debugf ("No colon in first line of depfile" )
91- return false , nil
92- }
93- objFileInDepFile := firstRow [:len (firstRow )- 1 ]
94- if objFileInDepFile != objectFile .String () {
95- logrus .Debugf ("Depfile is about different file: %v" , objFileInDepFile )
96- return false , nil
97- }
98-
99- // The first line of the depfile contains the path to the object file to generate.
100- // The second line of the depfile contains the path to the source file.
101- // All subsequent lines contain the header files necessary to compile the object file.
102-
103- // If we don't do this check it might happen that trying to compile a source file
104- // that has the same name but a different path wouldn't recreate the object file.
105- if sourceFile .String () != strings .Trim (rows [1 ], " " ) {
106- return false , nil
107- }
91+ if len (rows ) == 0 {
92+ return true , nil
93+ }
10894
109- rows = rows [1 :]
110- for _ , row := range rows {
111- depStat , err := os .Stat (row )
112- if err != nil && ! os .IsNotExist (err ) {
113- // There is probably a parsing error of the dep file
114- // Ignore the error and trigger a full rebuild anyway
115- logrus .WithError (err ).Debugf ("Failed to read: %v" , row )
95+ firstRow := rows [0 ]
96+ if ! strings .HasSuffix (firstRow , ":" ) {
97+ logrus .Debugf ("No colon in first line of depfile" )
11698 return false , nil
11799 }
118- if os .IsNotExist (err ) {
119- logrus .Debugf ("Not found: %v" , row )
100+ objFileInDepFile := firstRow [:len (firstRow )- 1 ]
101+ if objFileInDepFile != objectFile .String () {
102+ logrus .Debugf ("Depfile is about different object file: %v" , objFileInDepFile )
120103 return false , nil
121104 }
122- if depStat .ModTime ().After (objectFileStat .ModTime ()) {
123- logrus .Debugf ("%v newer than %v" , row , objectFile )
105+
106+ // The first line of the depfile contains the path to the object file to generate.
107+ // The second line of the depfile contains the path to the source file.
108+ // All subsequent lines contain the header files necessary to compile the object file.
109+
110+ // If we don't do this check it might happen that trying to compile a source file
111+ // that has the same name but a different path wouldn't recreate the object file.
112+ if sourceFile .String () != strings .Trim (rows [1 ], " " ) {
113+ logrus .Debugf ("Depfile is about different source file: %v" , strings .Trim (rows [1 ], " " ))
124114 return false , nil
125115 }
116+
117+ rows = rows [1 :]
118+ for _ , row := range rows {
119+ depStat , err := os .Stat (row )
120+ if err != nil && ! os .IsNotExist (err ) {
121+ // There is probably a parsing error of the dep file
122+ // Ignore the error and trigger a full rebuild anyway
123+ logrus .WithError (err ).Debugf ("Failed to read: %v" , row )
124+ return false , nil
125+ }
126+ if os .IsNotExist (err ) {
127+ logrus .Debugf ("Not found: %v" , row )
128+ return false , nil
129+ }
130+ if depStat .ModTime ().After (objectFileStat .ModTime ()) {
131+ logrus .Debugf ("%v newer than %v" , row , objectFile )
132+ return false , nil
133+ }
134+ }
135+
136+ return true , nil
126137 }
127138
128- return true , nil
139+ if runtime .GOOS == "windows" {
140+ // This is required because on Windows we don't know which encoding is used
141+ // by gcc to write the dep file (it could be UTF-8 or any of the Windows
142+ // ANSI mappings).
143+ if decoded , err := convertAnsiBytesToString (depFileData ); err == nil {
144+ if upToDate , err := checkDepFile (decoded ); err == nil && upToDate {
145+ return upToDate , nil
146+ }
147+ }
148+ // Fallback to UTF-8...
149+ }
150+ return checkDepFile (string (depFileData ))
129151}
130152
131153func removeEndingBackSlash (s string ) string {
0 commit comments