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(); | |
binji
2013/05/30 23:29:22
strange that source isn't used here.
| |
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; | |
206 | |
207 if (SkippedExecution) | |
208 { | |
209 return true; | |
210 } | |
211 | |
212 bool res = base.Execute(); | |
202 | 213 |
203 // Update tracker log files if execution occurred | 214 // Update tracker log files if execution occurred |
204 //if (this.skippedExecution == false) | 215 if (res && skippedExecution == false) |
binji
2013/05/30 23:29:22
skippedExecution should always be false here, corr
Sam Clegg
2013/05/30 23:48:57
Done.
| |
205 { | 216 { |
206 CanonicalTrackedOutputFiles outputs = OutputWriteTLog(compileSou rceList); | 217 CanonicalTrackedOutputFiles outputs = OutputWriteTLog(compileSou rceList); |
207 OutputReadTLog(compileSourceList, outputs); | 218 OutputReadTLog(compileSourceList, outputs); |
208 OutputCommandTLog(compileSourceList); | 219 OutputCommandTLog(compileSourceList); |
209 } | 220 } |
210 | 221 |
211 return returnResult; | 222 return res; |
212 } | 223 } |
213 | 224 |
214 protected override Encoding ResponseFileEncoding | 225 protected override Encoding ResponseFileEncoding |
215 { | 226 { |
216 get | 227 get |
217 { | 228 { |
218 return Encoding.ASCII; | 229 return Encoding.ASCII; |
219 } | 230 } |
220 } | 231 } |
221 | 232 |
222 protected virtual void SetTrackerLogPaths() | 233 protected virtual void SetTrackerLogPaths() |
223 { | 234 { |
224 if (this.TLogCommandFile == null) | 235 if (TLogCommandFile == null) |
225 { | 236 { |
226 string commandFile = Path.Combine(this.TlogDirectory, this.Comma ndTLogFilename); | 237 string commandFile = Path.Combine(TlogDirectory, CommandTLogFile name); |
227 this.TLogCommandFile = new TaskItem(commandFile); | 238 TLogCommandFile = new TaskItem(commandFile); |
228 } | 239 } |
229 | 240 |
230 if (this.TLogReadFiles == null) | 241 if (TLogReadFiles == null) |
231 { | 242 { |
232 this.TLogReadFiles = new ITaskItem[this.ReadTLogFilenames.Length ]; | 243 TLogReadFiles = new ITaskItem[ReadTLogFilenames.Length]; |
233 for (int n = 0; n < this.ReadTLogFilenames.Length; n++) | 244 for (int n = 0; n < ReadTLogFilenames.Length; n++) |
234 { | 245 { |
235 string readFile = Path.Combine(this.TlogDirectory, this.Read TLogFilenames[n]); | 246 string readFile = Path.Combine(TlogDirectory, ReadTLogFilena mes[n]); |
236 this.TLogReadFiles[n] = new TaskItem(readFile); | 247 TLogReadFiles[n] = new TaskItem(readFile); |
237 } | 248 } |
238 } | 249 } |
239 | 250 |
240 if (this.TLogWriteFiles == null) | 251 if (this.TLogWriteFiles == null) |
241 { | 252 { |
242 this.TLogWriteFiles = new ITaskItem[1]; | 253 TLogWriteFiles = new ITaskItem[1]; |
243 string writeFile = Path.Combine(this.TlogDirectory, this.WriteTL ogFilename); | 254 string writeFile = Path.Combine(TlogDirectory, WriteTLogFilename ); |
244 this.TLogWriteFiles[0] = new TaskItem(writeFile); | 255 TLogWriteFiles[0] = new TaskItem(writeFile); |
245 } | 256 } |
246 } | 257 } |
247 | 258 |
259 protected ITaskItem[] MergeOutOfDateSources(ITaskItem[] outOfDateSources FromTracking, | |
260 List<ITaskItem> outOfDateSourcesFromCommandLineChanges) | |
261 { | |
262 List<ITaskItem> mergedSources = new List<ITaskItem>(outOfDateSources FromTracking); | |
263 | |
264 foreach (ITaskItem item in outOfDateSourcesFromCommandLineChanges) | |
265 { | |
266 if (!mergedSources.Contains(item)) | |
267 { | |
268 mergedSources.Add(item); | |
269 } | |
270 } | |
271 | |
272 return mergedSources.ToArray(); | |
273 } | |
274 | |
275 protected virtual string GenerateCommandLineForSource(ITaskItem sourceFi le, bool fullOutputName = false) | |
276 { | |
277 return GenerateResponseFileCommands() ; | |
binji
2013/05/30 23:29:22
nit: remove space before ;
binji
2013/05/30 23:29:22
sourceFile not needed?
Sam Clegg
2013/05/30 23:48:57
Removed this function..
Sam Clegg
2013/05/30 23:48:57
Removed this function.
| |
278 } | |
279 | |
280 protected IDictionary<string, string> GenerateCommandLinesFromTlog() | |
281 { | |
282 IDictionary<string, string> cmdLineDictionary = new Dictionary<strin g, string>(StringComparer.OrdinalIgnoreCase); | |
283 string tlogFilename = this.TLogCommandFile.GetMetadata("FullPath"); | |
284 if (!File.Exists(tlogFilename)) | |
285 return cmdLineDictionary; | |
286 | |
287 using (StreamReader reader = File.OpenText(tlogFilename)) | |
288 { | |
289 string[] filenames = null; | |
290 for (string lineStr = reader.ReadLine(); lineStr != null; lineSt r = reader.ReadLine()) | |
291 { | |
292 if (lineStr.Length == 0 || (lineStr[0] == '^' && lineStr.Len gth == 1)) | |
293 { | |
294 Log.LogError("Invalid line in command tlog"); | |
295 break; | |
296 } | |
297 else if (lineStr[0] == '^') | |
298 { | |
299 filenames = lineStr.Substring(1).Split('|'); | |
300 } | |
301 else | |
302 { | |
303 foreach (string filename in filenames) | |
304 { | |
305 cmdLineDictionary[filename] = lineStr; | |
306 } | |
307 } | |
308 } | |
309 } | |
310 return cmdLineDictionary; | |
311 } | |
312 | |
313 protected List<ITaskItem> GetOutOfDateSourcesFromCmdLineChanges() | |
314 { | |
315 //get dictionary of source + command lines | |
316 IDictionary<string, string> dictionary = GenerateCommandLinesFromTlo g(); | |
317 List<ITaskItem> outOfDateSources = new List<ITaskItem>(); | |
318 | |
319 //add sources to out of date list if the tlog dictionary string do n ot match the generated command line string | |
320 StringBuilder currentCommandLine = new StringBuilder(GCCUtilities.s_ CommandLineLength); | |
321 foreach (ITaskItem sourceItem in Sources) | |
322 { | |
323 currentCommandLine.Length = 0; | |
324 currentCommandLine.Append(TLogCommandForSource(sourceItem)); | |
325 | |
326 string tlogCommandLine = null; | |
327 if (dictionary.TryGetValue(FileTracker.FormatRootingMarker(sourc eItem), out tlogCommandLine)) | |
328 { | |
329 if (tlogCommandLine == null || !currentCommandLine.ToString( ).Equals(tlogCommandLine, StringComparison.Ordinal)) | |
330 { | |
331 outOfDateSources.Add(sourceItem); | |
332 } | |
333 } | |
334 else | |
335 { | |
336 outOfDateSources.Add(sourceItem); | |
337 } | |
338 } | |
339 return outOfDateSources; | |
340 } | |
341 | |
342 protected void CalcSourcesToBuild() | |
343 { | |
344 //check if full recompile is required otherwise perform incremental | |
345 if (ForcedRebuildRequired() || MinimalRebuildFromTracking == false) | |
346 { | |
347 CompileSourceList = Sources; | |
348 return; | |
349 } | |
350 | |
351 //retrieve list of sources out of date due to command line changes | |
352 List<ITaskItem> outOfDateSourcesFromCommandLine = GetOutOfDateSource sFromCmdLineChanges(); | |
353 | |
354 //retrieve sources out of date due to tracking | |
355 CanonicalTrackedOutputFiles outputs = new CanonicalTrackedOutputFile s(this, TLogWriteFiles); | |
356 TrackedInputFiles = new CanonicalTrackedInputFiles(this, | |
357 TLogReadFiles, | |
358 Sources, | |
359 ExcludedInputPath s, | |
360 outputs, | |
361 true, | |
362 false); | |
363 ITaskItem[] outOfDateSourcesFromTracking = TrackedInputFiles.Compute SourcesNeedingCompilation(); | |
364 | |
365 //merge out of date lists | |
366 CompileSourceList = MergeOutOfDateSources(outOfDateSourcesFromTracki ng, outOfDateSourcesFromCommandLine); | |
367 if (CompileSourceList.Length == 0) | |
368 { | |
369 SkippedExecution = true; | |
370 return; | |
371 } | |
372 | |
373 //remove sources to compile from tracked file list | |
374 TrackedInputFiles.RemoveEntriesForSource(CompileSourceList); | |
375 outputs.RemoveEntriesForSource(CompileSourceList); | |
376 TrackedInputFiles.SaveTlog(); | |
377 outputs.SaveTlog(); | |
378 } | |
379 | |
248 [Output] | 380 [Output] |
249 public bool SkippedExecution | 381 public bool SkippedExecution |
250 { | 382 { |
251 get | 383 get |
252 { | 384 { |
253 return this.skippedExecution; | 385 return this.skippedExecution; |
254 } | 386 } |
255 set | 387 set |
256 { | 388 { |
257 this.skippedExecution = value; | 389 this.skippedExecution = value; |
258 } | 390 } |
259 } | 391 } |
260 | 392 |
393 [Output] | |
394 public ITaskItem[] CompileSourceList | |
395 { | |
396 get | |
397 { | |
398 return this.compileSourceList; | |
399 } | |
400 set | |
401 { | |
402 this.compileSourceList = value; | |
403 } | |
404 } | |
405 | |
261 public ITaskItem TLogCommandFile | 406 public ITaskItem TLogCommandFile |
262 { | 407 { |
263 get | 408 get |
264 { | 409 { |
265 return this.tlogCommandFile; | 410 return this.tlogCommandFile; |
266 } | 411 } |
267 set | 412 set |
268 { | 413 { |
269 this.tlogCommandFile = value; | 414 this.tlogCommandFile = value; |
270 } | 415 } |
271 } | 416 } |
272 | 417 |
273 protected string TlogDirectory | 418 protected string TlogDirectory |
274 { | 419 { |
275 get | 420 get |
276 { | 421 { |
277 if (this.TrackerLogDirectory != null) | 422 if (this.TrackerLogDirectory != null) |
278 { | 423 { |
279 return this.TrackerLogDirectory; | 424 return this.TrackerLogDirectory; |
280 } | 425 } |
281 return string.Empty; | 426 return string.Empty; |
282 } | 427 } |
283 } | 428 } |
284 | 429 |
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 | 430 public ITaskItem[] TLogReadFiles |
299 { | 431 { |
300 get | 432 get |
301 { | 433 { |
302 return this.tlogReadFiles; | 434 return this.tlogReadFiles; |
303 } | 435 } |
304 set | 436 set |
305 { | 437 { |
306 this.tlogReadFiles = value; | 438 this.tlogReadFiles = value; |
307 } | 439 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
348 get | 480 get |
349 { | 481 { |
350 return this.excludedInputPaths; | 482 return this.excludedInputPaths; |
351 } | 483 } |
352 set | 484 set |
353 { | 485 { |
354 this.excludedInputPaths = value; | 486 this.excludedInputPaths = value; |
355 } | 487 } |
356 } | 488 } |
357 | 489 |
358 protected virtual string CommandTLogFilename | 490 protected abstract string CommandTLogFilename { get; } |
359 { | |
360 get | |
361 { | |
362 return BaseTool() + ".compile.command.1.tlog"; | |
363 } | |
364 } | |
365 | 491 |
366 protected virtual string[] ReadTLogFilenames | 492 protected abstract string WriteTLogFilename { get; } |
367 { | |
368 get | |
369 { | |
370 return new string[] { BaseTool() + ".compile.read.1.tlog" }; | |
371 } | |
372 } | |
373 | 493 |
374 protected virtual string WriteTLogFilename | 494 protected abstract string[] ReadTLogFilenames { get; } |
375 { | |
376 get | |
377 { | |
378 return BaseTool() + ".compile.write.1.tlog"; | |
379 } | |
380 } | |
381 | 495 |
382 public virtual string PlatformToolset | 496 public virtual string PlatformToolset |
383 { | 497 { |
384 get | 498 get |
385 { | 499 { |
386 return "GCC"; | 500 return "GCC"; |
387 } | 501 } |
388 } | 502 } |
389 | 503 |
390 protected override string GenerateFullPathToTool() | 504 protected override string GenerateFullPathToTool() |
391 { | 505 { |
392 return this.ToolName; | 506 return this.ToolName; |
393 } | 507 } |
394 } | 508 } |
395 } | 509 } |
OLD | NEW |