OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 using System; | 4 using System; |
5 using System.Collections.Generic; | 5 using System.Collections.Generic; |
6 using System.Text; | 6 using System.Text; |
7 using System.Collections; | 7 using System.Collections; |
8 using System.IO; | 8 using System.IO; |
9 using System.Reflection; | 9 using System.Reflection; |
10 using System.Resources; | 10 using System.Resources; |
(...skipping 10 matching lines...) Expand all Loading... |
21 public abstract class NaClToolTask : ToolTask | 21 public abstract class NaClToolTask : ToolTask |
22 { | 22 { |
23 protected NaClToolTask(ResourceManager taskResources) : base(taskResourc
es) { } | 23 protected NaClToolTask(ResourceManager taskResources) : base(taskResourc
es) { } |
24 public bool BuildingInIDE { get; set; } | 24 public bool BuildingInIDE { get; set; } |
25 protected ITaskItem[] excludedInputPaths; | 25 protected ITaskItem[] excludedInputPaths; |
26 private ITaskItem[] tlogReadFiles; | 26 private ITaskItem[] tlogReadFiles; |
27 private ITaskItem tlogCommandFile; | 27 private ITaskItem tlogCommandFile; |
28 private ITaskItem[] tlogWriteFiles; | 28 private ITaskItem[] tlogWriteFiles; |
29 private CanonicalTrackedInputFiles trackedInputFiles; | 29 private CanonicalTrackedInputFiles trackedInputFiles; |
30 private bool skippedExecution; | 30 private bool skippedExecution; |
31 private bool minimalRebuildFromTracking; | |
32 private bool trackFileAccess; | 31 private bool trackFileAccess; |
33 protected ITaskItem[] compileSourceList; | 32 protected ITaskItem[] compileSourceList; |
34 protected XamlParser xamlParser; | 33 protected XamlParser xamlParser; |
35 | 34 |
36 [Required] | 35 [Required] |
| 36 public string PropertiesFile { get; set; } |
| 37 |
| 38 [Required] |
37 public string TrackerLogDirectory { get; set; } | 39 public string TrackerLogDirectory { get; set; } |
38 | 40 |
39 [Required] | 41 [Required] |
40 public virtual ITaskItem[] Sources { get; set; } | 42 public virtual ITaskItem[] Sources { get; set; } |
41 | 43 |
42 [Required] | 44 [Required] |
43 public bool OutputCommandLine { get; set; } | 45 public bool OutputCommandLine { get; set; } |
44 | 46 |
45 [Required] | 47 [Required] |
| 48 public bool MinimalRebuildFromTracking { get; set; } |
| 49 |
| 50 [Required] |
46 public string Platform { get; set; } | 51 public string Platform { get; set; } |
47 | 52 |
48 public virtual string OutputFile { get; set; } | 53 public virtual string OutputFile { get; set; } |
49 | 54 |
50 // Override default StandardOutputLoggingImportance so that we see the s
tdout from the | 55 // Override default StandardOutputLoggingImportance so that we see the s
tdout from the |
51 // toolchain from within visual studio. | 56 // toolchain from within visual studio. |
52 protected override MessageImportance StandardOutputLoggingImportance | 57 protected override MessageImportance StandardOutputLoggingImportance |
53 { | 58 { |
54 get { return MessageImportance.Normal; } | 59 get { return MessageImportance.Normal; } |
55 } | 60 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 return Path.GetFileNameWithoutExtension(ToolName); | 96 return Path.GetFileNameWithoutExtension(ToolName); |
92 } | 97 } |
93 | 98 |
94 protected bool IsPNaCl() | 99 protected bool IsPNaCl() |
95 { | 100 { |
96 return Platform.Equals("pnacl", StringComparison.OrdinalIgnoreCase); | 101 return Platform.Equals("pnacl", StringComparison.OrdinalIgnoreCase); |
97 } | 102 } |
98 | 103 |
99 protected bool Setup() | 104 protected bool Setup() |
100 { | 105 { |
101 this.SkippedExecution = false; | 106 SkippedExecution = false; |
102 | |
103 if (!ValidateParameters()) | 107 if (!ValidateParameters()) |
104 { | 108 { |
105 return false; | 109 return false; |
106 } | 110 } |
107 | 111 |
108 if (IsPNaCl()) | 112 if (IsPNaCl()) |
109 { | 113 { |
110 if (!SDKUtilities.FindPython()) | 114 if (!SDKUtilities.FindPython()) |
111 { | 115 { |
112 Log.LogError("PNaCl linking requires python in your executab
le path."); | 116 Log.LogError("PNaCl linking requires python in your executab
le path."); |
113 return false; | 117 return false; |
114 } | 118 } |
115 } | 119 } |
116 | 120 |
117 if (this.TrackFileAccess || this.MinimalRebuildFromTracking) | 121 if (TrackFileAccess || MinimalRebuildFromTracking) |
118 { | 122 { |
119 this.SetTrackerLogPaths(); | 123 SetTrackerLogPaths(); |
120 } | 124 } |
121 | 125 |
122 if (this.ForcedRebuildRequired() || this.MinimalRebuildFromTracking
== false) | 126 CalcSourcesToBuild(); |
123 { | |
124 if (this.Sources == null || this.Sources.Length == 0) | |
125 { | |
126 this.SkippedExecution = true; | |
127 } | |
128 } | |
129 | |
130 return true; | 127 return true; |
131 } | 128 } |
132 | 129 |
133 protected virtual CanonicalTrackedOutputFiles OutputWriteTLog(ITaskItem[
] inputs) | 130 protected virtual CanonicalTrackedOutputFiles OutputWriteTLog(ITaskItem[
] inputs) |
134 { | 131 { |
135 string path = Path.Combine(TlogDirectory, WriteTLogFilename); | 132 string path = Path.Combine(TlogDirectory, WriteTLogFilename); |
136 TaskItem item = new TaskItem(path); | 133 TaskItem item = new TaskItem(path); |
137 CanonicalTrackedOutputFiles trackedFiles = | 134 CanonicalTrackedOutputFiles trackedFiles = |
138 new CanonicalTrackedOutputFiles(new TaskItem[] { item }); | 135 new CanonicalTrackedOutputFiles(new TaskItem[] { item }); |
139 | 136 |
(...skipping 30 matching lines...) Expand all Loading... |
170 | 167 |
171 writer.WriteLine("^" + sourcePath); | 168 writer.WriteLine("^" + sourcePath); |
172 foreach (ITaskItem source in Sources) | 169 foreach (ITaskItem source in Sources) |
173 { | 170 { |
174 writer.WriteLine(Path.GetFullPath(source.ItemSpec).ToUpperIn
variant()); | 171 writer.WriteLine(Path.GetFullPath(source.ItemSpec).ToUpperIn
variant()); |
175 } | 172 } |
176 writer.WriteLine(Path.GetFullPath(OutputFile).ToUpperInvariant()
); | 173 writer.WriteLine(Path.GetFullPath(OutputFile).ToUpperInvariant()
); |
177 } | 174 } |
178 } | 175 } |
179 | 176 |
| 177 protected virtual string TLogCommandForSource(ITaskItem source) |
| 178 { |
| 179 return GenerateResponseFileCommands(); |
| 180 } |
| 181 |
180 protected virtual void OutputCommandTLog(ITaskItem[] compiledSources) | 182 protected virtual void OutputCommandTLog(ITaskItem[] compiledSources) |
181 { | 183 { |
182 string fullpath = TLogCommandFile.GetMetadata("FullPath"); | 184 string fullpath = TLogCommandFile.GetMetadata("FullPath"); |
183 using (var writer = new StreamWriter(fullpath, false, Encoding.Unico
de)) | 185 using (var writer = new StreamWriter(fullpath, false, Encoding.Unico
de)) |
184 { | 186 { |
185 string cmds = GenerateResponseFileCommands(); | 187 string cmds = TLogCommandForSource(Sources[0]); |
186 string sourcePath = ""; | 188 string sourcePath = ""; |
187 foreach (ITaskItem source in Sources) | 189 foreach (ITaskItem source in Sources) |
188 { | 190 { |
189 if (sourcePath != "") | 191 if (sourcePath != "") |
190 sourcePath += "|"; | 192 sourcePath += "|"; |
191 sourcePath += Path.GetFullPath(source.ItemSpec).ToUpperInvar
iant(); | 193 sourcePath += Path.GetFullPath(source.ItemSpec).ToUpperInvar
iant(); |
192 } | 194 } |
193 | 195 |
194 writer.WriteLine("^" + sourcePath); | 196 writer.WriteLine("^" + sourcePath); |
195 writer.WriteLine(cmds); | 197 writer.WriteLine(cmds); |
196 } | 198 } |
197 } | 199 } |
198 | 200 |
199 public override bool Execute() | 201 public override bool Execute() |
200 { | 202 { |
201 bool returnResult = base.Execute(); | 203 xamlParser = new XamlParser(PropertiesFile); |
| 204 if (!Setup()) |
| 205 return false; |
202 | 206 |
203 // Update tracker log files if execution occurred | 207 if (SkippedExecution) |
204 //if (this.skippedExecution == false) | 208 return true; |
| 209 |
| 210 bool res = base.Execute(); |
| 211 // Update tracker log files if execution was successful |
| 212 if (res) |
205 { | 213 { |
206 CanonicalTrackedOutputFiles outputs = OutputWriteTLog(compileSou
rceList); | 214 CanonicalTrackedOutputFiles outputs = OutputWriteTLog(compileSou
rceList); |
207 OutputReadTLog(compileSourceList, outputs); | 215 OutputReadTLog(compileSourceList, outputs); |
208 OutputCommandTLog(compileSourceList); | 216 OutputCommandTLog(compileSourceList); |
209 } | 217 } |
210 | 218 |
211 return returnResult; | 219 return res; |
212 } | 220 } |
213 | 221 |
214 protected override Encoding ResponseFileEncoding | 222 protected override Encoding ResponseFileEncoding |
215 { | 223 { |
216 get | 224 get |
217 { | 225 { |
218 return Encoding.ASCII; | 226 return Encoding.ASCII; |
219 } | 227 } |
220 } | 228 } |
221 | 229 |
222 protected virtual void SetTrackerLogPaths() | 230 protected virtual void SetTrackerLogPaths() |
223 { | 231 { |
224 if (this.TLogCommandFile == null) | 232 if (TLogCommandFile == null) |
225 { | 233 { |
226 string commandFile = Path.Combine(this.TlogDirectory, this.Comma
ndTLogFilename); | 234 string commandFile = Path.Combine(TlogDirectory, CommandTLogFile
name); |
227 this.TLogCommandFile = new TaskItem(commandFile); | 235 TLogCommandFile = new TaskItem(commandFile); |
228 } | 236 } |
229 | 237 |
230 if (this.TLogReadFiles == null) | 238 if (TLogReadFiles == null) |
231 { | 239 { |
232 this.TLogReadFiles = new ITaskItem[this.ReadTLogFilenames.Length
]; | 240 TLogReadFiles = new ITaskItem[ReadTLogFilenames.Length]; |
233 for (int n = 0; n < this.ReadTLogFilenames.Length; n++) | 241 for (int n = 0; n < ReadTLogFilenames.Length; n++) |
234 { | 242 { |
235 string readFile = Path.Combine(this.TlogDirectory, this.Read
TLogFilenames[n]); | 243 string readFile = Path.Combine(TlogDirectory, ReadTLogFilena
mes[n]); |
236 this.TLogReadFiles[n] = new TaskItem(readFile); | 244 TLogReadFiles[n] = new TaskItem(readFile); |
237 } | 245 } |
238 } | 246 } |
239 | 247 |
240 if (this.TLogWriteFiles == null) | 248 if (this.TLogWriteFiles == null) |
241 { | 249 { |
242 this.TLogWriteFiles = new ITaskItem[1]; | 250 TLogWriteFiles = new ITaskItem[1]; |
243 string writeFile = Path.Combine(this.TlogDirectory, this.WriteTL
ogFilename); | 251 string writeFile = Path.Combine(TlogDirectory, WriteTLogFilename
); |
244 this.TLogWriteFiles[0] = new TaskItem(writeFile); | 252 TLogWriteFiles[0] = new TaskItem(writeFile); |
245 } | 253 } |
246 } | 254 } |
247 | 255 |
| 256 protected ITaskItem[] MergeOutOfDateSources(ITaskItem[] outOfDateSources
FromTracking, |
| 257 List<ITaskItem> outOfDateSou
rcesFromCommandLineChanges) |
| 258 { |
| 259 List<ITaskItem> mergedSources = new List<ITaskItem>(outOfDateSources
FromTracking); |
| 260 |
| 261 foreach (ITaskItem item in outOfDateSourcesFromCommandLineChanges) |
| 262 { |
| 263 if (!mergedSources.Contains(item)) |
| 264 { |
| 265 mergedSources.Add(item); |
| 266 } |
| 267 } |
| 268 |
| 269 return mergedSources.ToArray(); |
| 270 } |
| 271 |
| 272 protected IDictionary<string, string> GenerateCommandLinesFromTlog() |
| 273 { |
| 274 IDictionary<string, string> cmdLineDictionary = new Dictionary<strin
g, string>(StringComparer.OrdinalIgnoreCase); |
| 275 string tlogFilename = this.TLogCommandFile.GetMetadata("FullPath"); |
| 276 if (!File.Exists(tlogFilename)) |
| 277 return cmdLineDictionary; |
| 278 |
| 279 using (StreamReader reader = File.OpenText(tlogFilename)) |
| 280 { |
| 281 string[] filenames = null; |
| 282 for (string lineStr = reader.ReadLine(); lineStr != null; lineSt
r = reader.ReadLine()) |
| 283 { |
| 284 if (lineStr.Length == 0 || (lineStr[0] == '^' && lineStr.Len
gth == 1)) |
| 285 { |
| 286 Log.LogError("Invalid line in command tlog"); |
| 287 break; |
| 288 } |
| 289 else if (lineStr[0] == '^') |
| 290 { |
| 291 filenames = lineStr.Substring(1).Split('|'); |
| 292 } |
| 293 else |
| 294 { |
| 295 foreach (string filename in filenames) |
| 296 { |
| 297 cmdLineDictionary[filename] = lineStr; |
| 298 } |
| 299 } |
| 300 } |
| 301 } |
| 302 return cmdLineDictionary; |
| 303 } |
| 304 |
| 305 protected List<ITaskItem> GetOutOfDateSourcesFromCmdLineChanges() |
| 306 { |
| 307 //get dictionary of source + command lines |
| 308 IDictionary<string, string> dictionary = GenerateCommandLinesFromTlo
g(); |
| 309 List<ITaskItem> outOfDateSources = new List<ITaskItem>(); |
| 310 |
| 311 //add sources to out of date list if the tlog dictionary string do n
ot match the generated command line string |
| 312 StringBuilder currentCommandLine = new StringBuilder(GCCUtilities.s_
CommandLineLength); |
| 313 foreach (ITaskItem sourceItem in Sources) |
| 314 { |
| 315 currentCommandLine.Length = 0; |
| 316 currentCommandLine.Append(TLogCommandForSource(sourceItem)); |
| 317 |
| 318 string tlogCommandLine = null; |
| 319 if (dictionary.TryGetValue(FileTracker.FormatRootingMarker(sourc
eItem), out tlogCommandLine)) |
| 320 { |
| 321 if (tlogCommandLine == null || !currentCommandLine.ToString(
).Equals(tlogCommandLine, StringComparison.Ordinal)) |
| 322 { |
| 323 outOfDateSources.Add(sourceItem); |
| 324 } |
| 325 } |
| 326 else |
| 327 { |
| 328 outOfDateSources.Add(sourceItem); |
| 329 } |
| 330 } |
| 331 return outOfDateSources; |
| 332 } |
| 333 |
| 334 protected void CalcSourcesToBuild() |
| 335 { |
| 336 //check if full recompile is required otherwise perform incremental |
| 337 if (ForcedRebuildRequired() || MinimalRebuildFromTracking == false) |
| 338 { |
| 339 CompileSourceList = Sources; |
| 340 return; |
| 341 } |
| 342 |
| 343 //retrieve list of sources out of date due to command line changes |
| 344 List<ITaskItem> outOfDateSourcesFromCommandLine = GetOutOfDateSource
sFromCmdLineChanges(); |
| 345 |
| 346 //retrieve sources out of date due to tracking |
| 347 CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFile
s(this, TLogWriteFiles); |
| 348 TrackedInputFiles = new CanonicalTrackedInputFiles(this, |
| 349 TLogReadFiles, |
| 350 Sources, |
| 351 ExcludedInputPath
s, |
| 352 outputs, |
| 353 true, |
| 354 false); |
| 355 ITaskItem[] outOfDateSourcesFromTracking = TrackedInputFiles.Compute
SourcesNeedingCompilation(); |
| 356 |
| 357 //merge out of date lists |
| 358 CompileSourceList = MergeOutOfDateSources(outOfDateSourcesFromTracki
ng, outOfDateSourcesFromCommandLine); |
| 359 if (CompileSourceList.Length == 0) |
| 360 { |
| 361 SkippedExecution = true; |
| 362 return; |
| 363 } |
| 364 |
| 365 //remove sources to compile from tracked file list |
| 366 TrackedInputFiles.RemoveEntriesForSource(CompileSourceList); |
| 367 outputs.RemoveEntriesForSource(CompileSourceList); |
| 368 TrackedInputFiles.SaveTlog(); |
| 369 outputs.SaveTlog(); |
| 370 } |
| 371 |
248 [Output] | 372 [Output] |
249 public bool SkippedExecution | 373 public bool SkippedExecution |
250 { | 374 { |
251 get | 375 get |
252 { | 376 { |
253 return this.skippedExecution; | 377 return this.skippedExecution; |
254 } | 378 } |
255 set | 379 set |
256 { | 380 { |
257 this.skippedExecution = value; | 381 this.skippedExecution = value; |
258 } | 382 } |
259 } | 383 } |
260 | 384 |
| 385 [Output] |
| 386 public ITaskItem[] CompileSourceList |
| 387 { |
| 388 get |
| 389 { |
| 390 return this.compileSourceList; |
| 391 } |
| 392 set |
| 393 { |
| 394 this.compileSourceList = value; |
| 395 } |
| 396 } |
| 397 |
261 public ITaskItem TLogCommandFile | 398 public ITaskItem TLogCommandFile |
262 { | 399 { |
263 get | 400 get |
264 { | 401 { |
265 return this.tlogCommandFile; | 402 return this.tlogCommandFile; |
266 } | 403 } |
267 set | 404 set |
268 { | 405 { |
269 this.tlogCommandFile = value; | 406 this.tlogCommandFile = value; |
270 } | 407 } |
271 } | 408 } |
272 | 409 |
273 protected string TlogDirectory | 410 protected string TlogDirectory |
274 { | 411 { |
275 get | 412 get |
276 { | 413 { |
277 if (this.TrackerLogDirectory != null) | 414 if (this.TrackerLogDirectory != null) |
278 { | 415 { |
279 return this.TrackerLogDirectory; | 416 return this.TrackerLogDirectory; |
280 } | 417 } |
281 return string.Empty; | 418 return string.Empty; |
282 } | 419 } |
283 } | 420 } |
284 | 421 |
285 public bool MinimalRebuildFromTracking | |
286 { | |
287 get | |
288 { | |
289 return this.minimalRebuildFromTracking; | |
290 } | |
291 set | |
292 { | |
293 this.minimalRebuildFromTracking = value; | |
294 } | |
295 } | |
296 | |
297 | |
298 public ITaskItem[] TLogReadFiles | 422 public ITaskItem[] TLogReadFiles |
299 { | 423 { |
300 get | 424 get |
301 { | 425 { |
302 return this.tlogReadFiles; | 426 return this.tlogReadFiles; |
303 } | 427 } |
304 set | 428 set |
305 { | 429 { |
306 this.tlogReadFiles = value; | 430 this.tlogReadFiles = value; |
307 } | 431 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 get | 472 get |
349 { | 473 { |
350 return this.excludedInputPaths; | 474 return this.excludedInputPaths; |
351 } | 475 } |
352 set | 476 set |
353 { | 477 { |
354 this.excludedInputPaths = value; | 478 this.excludedInputPaths = value; |
355 } | 479 } |
356 } | 480 } |
357 | 481 |
358 protected virtual string CommandTLogFilename | 482 protected abstract string CommandTLogFilename { get; } |
359 { | |
360 get | |
361 { | |
362 return BaseTool() + ".compile.command.1.tlog"; | |
363 } | |
364 } | |
365 | 483 |
366 protected virtual string[] ReadTLogFilenames | 484 protected abstract string WriteTLogFilename { get; } |
367 { | |
368 get | |
369 { | |
370 return new string[] { BaseTool() + ".compile.read.1.tlog" }; | |
371 } | |
372 } | |
373 | 485 |
374 protected virtual string WriteTLogFilename | 486 protected abstract string[] ReadTLogFilenames { get; } |
375 { | |
376 get | |
377 { | |
378 return BaseTool() + ".compile.write.1.tlog"; | |
379 } | |
380 } | |
381 | 487 |
382 public virtual string PlatformToolset | 488 public virtual string PlatformToolset |
383 { | 489 { |
384 get | 490 get |
385 { | 491 { |
386 return "GCC"; | 492 return "GCC"; |
387 } | 493 } |
388 } | 494 } |
389 | 495 |
390 protected override string GenerateFullPathToTool() | 496 protected override string GenerateFullPathToTool() |
391 { | 497 { |
392 return this.ToolName; | 498 return this.ToolName; |
393 } | 499 } |
394 } | 500 } |
395 } | 501 } |
OLD | NEW |