@@ -17,6 +17,7 @@ package utils
17
17
18
18
import (
19
19
"os"
20
+ "runtime"
20
21
"strings"
21
22
"unicode"
22
23
@@ -32,33 +33,36 @@ import (
32
33
func ObjFileIsUpToDate (sourceFile , objectFile , dependencyFile * paths.Path ) (bool , error ) {
33
34
logrus .Debugf ("Checking previous results for %v (result = %v, dep = %v)" , sourceFile , objectFile , dependencyFile )
34
35
if objectFile == nil || dependencyFile == nil {
35
- logrus .Debugf ("Not found: nil " )
36
+ logrus .Debugf ("Object file or dependency file not provided " )
36
37
return false , nil
37
38
}
38
39
39
40
sourceFile = sourceFile .Clean ()
40
41
sourceFileStat , err := sourceFile .Stat ()
41
42
if err != nil {
43
+ logrus .Debugf ("Could not stat source file: %s" , err )
42
44
return false , err
43
45
}
44
46
45
47
objectFile = objectFile .Clean ()
46
48
objectFileStat , err := objectFile .Stat ()
47
49
if err != nil {
48
50
if os .IsNotExist (err ) {
49
- logrus .Debugf ("Not found: %v" , objectFile )
51
+ logrus .Debugf ("Object file not found: %v" , objectFile )
50
52
return false , nil
51
53
}
54
+ logrus .Debugf ("Could not stat object file: %s" , err )
52
55
return false , err
53
56
}
54
57
55
58
dependencyFile = dependencyFile .Clean ()
56
59
dependencyFileStat , err := dependencyFile .Stat ()
57
60
if err != nil {
58
61
if os .IsNotExist (err ) {
59
- logrus .Debugf ("Not found: %v" , dependencyFile )
62
+ logrus .Debugf ("Dependency file not found: %v" , dependencyFile )
60
63
return false , nil
61
64
}
65
+ logrus .Debugf ("Could not stat dependency file: %s" , err )
62
66
return false , err
63
67
}
64
68
@@ -71,61 +75,79 @@ func ObjFileIsUpToDate(sourceFile, objectFile, dependencyFile *paths.Path) (bool
71
75
return false , nil
72
76
}
73
77
74
- rows , err := dependencyFile .ReadFileAsLines ()
78
+ depFileData , err := dependencyFile .ReadFile ()
75
79
if err != nil {
80
+ logrus .Debugf ("Could not read dependency file: %s" , dependencyFile )
76
81
return false , err
77
82
}
78
83
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 ("" ))
83
90
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
+ }
108
94
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" )
116
98
return false , nil
117
99
}
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 )
120
103
return false , nil
121
104
}
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 ], " " ))
124
114
return false , nil
125
115
}
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
126
137
}
127
138
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 ))
129
151
}
130
152
131
153
func removeEndingBackSlash (s string ) string {
0 commit comments