@@ -17,6 +17,7 @@ package utils
17
17
18
18
import (
19
19
"os"
20
+ "runtime"
20
21
"strings"
21
22
"unicode"
22
23
@@ -74,63 +75,79 @@ func ObjFileIsUpToDate(sourceFile, objectFile, dependencyFile *paths.Path) (bool
74
75
return false , nil
75
76
}
76
77
77
- rows , err := dependencyFile .ReadFileAsLines ()
78
+ depFileData , err := dependencyFile .ReadFile ()
78
79
if err != nil {
79
80
logrus .Debugf ("Could not read dependency file: %s" , dependencyFile )
80
81
return false , err
81
82
}
82
83
83
- rows = f .Map (rows , removeEndingBackSlash )
84
- rows = f .Map (rows , strings .TrimSpace )
85
- rows = f .Map (rows , unescapeDep )
86
- 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 ("" ))
87
90
88
- if len (rows ) == 0 {
89
- return true , nil
90
- }
91
-
92
- firstRow := rows [0 ]
93
- if ! strings .HasSuffix (firstRow , ":" ) {
94
- logrus .Debugf ("No colon in first line of depfile" )
95
- return false , nil
96
- }
97
- objFileInDepFile := firstRow [:len (firstRow )- 1 ]
98
- if objFileInDepFile != objectFile .String () {
99
- logrus .Debugf ("Depfile is about different object file: %v" , objFileInDepFile )
100
- return false , nil
101
- }
102
-
103
- // The first line of the depfile contains the path to the object file to generate.
104
- // The second line of the depfile contains the path to the source file.
105
- // All subsequent lines contain the header files necessary to compile the object file.
106
-
107
- // If we don't do this check it might happen that trying to compile a source file
108
- // that has the same name but a different path wouldn't recreate the object file.
109
- if sourceFile .String () != strings .Trim (rows [1 ], " " ) {
110
- logrus .Debugf ("Depfile is about different source file: %v" , strings .Trim (rows [1 ], " " ))
111
- return false , nil
112
- }
91
+ if len (rows ) == 0 {
92
+ return true , nil
93
+ }
113
94
114
- rows = rows [1 :]
115
- for _ , row := range rows {
116
- depStat , err := os .Stat (row )
117
- if err != nil && ! os .IsNotExist (err ) {
118
- // There is probably a parsing error of the dep file
119
- // Ignore the error and trigger a full rebuild anyway
120
- 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" )
121
98
return false , nil
122
99
}
123
- if os .IsNotExist (err ) {
124
- 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 )
125
103
return false , nil
126
104
}
127
- if depStat .ModTime ().After (objectFileStat .ModTime ()) {
128
- 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 ], " " ))
129
114
return false , nil
130
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
131
137
}
132
138
133
- 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 (string (decoded )); err == nil && upToDate {
145
+ return upToDate , nil
146
+ }
147
+ }
148
+ // Fallback to UTF-8...
149
+ }
150
+ return checkDepFile (string (depFileData ))
134
151
}
135
152
136
153
func removeEndingBackSlash (s string ) string {
0 commit comments