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; |
11 using System.Windows.Forms; | 11 using System.Windows.Forms; |
12 using Microsoft.Build.Framework; | 12 using Microsoft.Build.Framework; |
13 using Microsoft.Win32; | 13 using Microsoft.Win32; |
14 using Microsoft.Build.Utilities; | 14 using Microsoft.Build.Utilities; |
15 using System.Collections.Specialized; | 15 using System.Collections.Specialized; |
16 | 16 |
17 using System.Diagnostics; | 17 using System.Diagnostics; |
18 | 18 |
19 namespace NaCl.Build.CPPTasks | 19 namespace NaCl.Build.CPPTasks |
20 { | 20 { |
21 public class NaClCompile : NaClToolTask | 21 public class NaClCompile : NaClToolTask |
22 { | 22 { |
23 [Required] | 23 [Required] |
24 public string PropertiesFile { get; set; } | |
25 | |
26 [Required] | |
27 public string NaCLCompilerPath { get; set; } | 24 public string NaCLCompilerPath { get; set; } |
28 | 25 |
29 public int ProcessorNumber { get; set; } | 26 public int ProcessorNumber { get; set; } |
30 | 27 |
31 public bool MultiProcessorCompilation { get; set; } | 28 public bool MultiProcessorCompilation { get; set; } |
32 | 29 |
33 [Required] | 30 [Required] |
34 public string ConfigurationType { get; set; } | 31 public string ConfigurationType { get; set; } |
35 | 32 |
36 [Obsolete] | 33 [Obsolete] |
37 protected override StringDictionary EnvironmentOverride | 34 protected override StringDictionary EnvironmentOverride |
38 { | 35 { |
39 get { | 36 get { |
40 string show = OutputCommandLine ? "1" : "0"; | 37 string show = OutputCommandLine ? "1" : "0"; |
41 string cores = Convert.ToString(ProcessorNumber); | 38 string cores = Convert.ToString(ProcessorNumber); |
42 return new StringDictionary() { | 39 return new StringDictionary() { |
43 {"NACL_GCC_CORES", cores}, | 40 {"NACL_GCC_CORES", cores}, |
44 {"NACL_GCC_SHOW_COMMANDS", show } | 41 {"NACL_GCC_SHOW_COMMANDS", show } |
45 }; | 42 }; |
46 } | 43 } |
47 } | 44 } |
48 | 45 |
49 public NaClCompile() | 46 public NaClCompile() |
50 : base(new ResourceManager("NaCl.Build.CPPTasks.Properties.Resources ", Assembly.GetExecutingAssembly())) | 47 : base(new ResourceManager("NaCl.Build.CPPTasks.Properties.Resources ", Assembly.GetExecutingAssembly())) |
51 { | 48 { |
52 this.EnvironmentVariables = new string[] { "CYGWIN=nodosfilewarning" , "LC_CTYPE=C" }; | 49 this.EnvironmentVariables = new string[] { "CYGWIN=nodosfilewarning" , "LC_CTYPE=C" }; |
53 } | 50 } |
54 | 51 |
55 protected IDictionary<string, string> GenerateCommandLinesFromTlog() | |
56 { | |
57 IDictionary<string, string> cmdLineDictionary = new Dictionary<strin g, string>(StringComparer.OrdinalIgnoreCase); | |
58 string tlogFilename = this.TLogCommandFile.GetMetadata("FullPath"); | |
59 if (File.Exists(tlogFilename)) | |
60 { | |
61 using (StreamReader reader = File.OpenText(tlogFilename)) | |
62 { | |
63 string filename = string.Empty; | |
64 for (string lineStr = reader.ReadLine(); lineStr != null; li neStr = reader.ReadLine()) | |
65 { | |
66 if (lineStr.Length == 0 || | |
67 (lineStr[0] == '^' && lineStr.Length == 1)) | |
68 { | |
69 Log.LogError("Invalid line in command tlog"); | |
70 break; | |
71 } | |
72 else if (lineStr[0] == '^') | |
73 { | |
74 filename = lineStr.Substring(1); | |
75 } | |
76 else | |
77 { | |
78 cmdLineDictionary[filename] = lineStr; | |
79 } | |
80 } | |
81 } | |
82 } | |
83 return cmdLineDictionary; | |
84 } | |
85 | |
86 protected override void LogEventsFromTextOutput(string singleLine, Messa geImportance messageImportance) | 52 protected override void LogEventsFromTextOutput(string singleLine, Messa geImportance messageImportance) |
87 { | 53 { |
88 base.LogEventsFromTextOutput(GCCUtilities.ConvertGCCOutput(singleLin e), messageImportance); | 54 base.LogEventsFromTextOutput(GCCUtilities.ConvertGCCOutput(singleLin e), messageImportance); |
89 } | 55 } |
90 | 56 |
91 static string GetObjectFile(ITaskItem source) | 57 static string GetObjectFile(ITaskItem source) |
92 { | 58 { |
93 string objectFilePath = Path.GetFullPath(source.GetMetadata("ObjectF ileName")); | 59 string objectFilePath = Path.GetFullPath(source.GetMetadata("ObjectF ileName")); |
94 // cl.exe will accept a folder name as the ObjectFileName in which c ase | 60 // cl.exe will accept a folder name as the ObjectFileName in which c ase |
95 // the objectfile is created as <ObjectFileName>/<basename>.obj. He re | 61 // the objectfile is created as <ObjectFileName>/<basename>.obj. He re |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 trackedFiles.AddComputedOutputForSourceRoot(Path.GetFullPath(sou rceItem.ItemSpec).ToUpperInvariant(), | 147 trackedFiles.AddComputedOutputForSourceRoot(Path.GetFullPath(sou rceItem.ItemSpec).ToUpperInvariant(), |
182 Path.GetFullPath(Get ObjectFile(sourceItem)).ToUpperInvariant()); | 148 Path.GetFullPath(Get ObjectFile(sourceItem)).ToUpperInvariant()); |
183 } | 149 } |
184 | 150 |
185 //output tlog | 151 //output tlog |
186 trackedFiles.SaveTlog(); | 152 trackedFiles.SaveTlog(); |
187 | 153 |
188 return trackedFiles; | 154 return trackedFiles; |
189 } | 155 } |
190 | 156 |
157 protected override string TLogCommandForSource(ITaskItem source) | |
158 { | |
159 return GenerateCommandLineForSource(source) + " " + source.GetMetada ta("FullPath").ToUpperInvariant(); | |
160 } | |
161 | |
191 protected override void OutputCommandTLog(ITaskItem[] compiledSources) | 162 protected override void OutputCommandTLog(ITaskItem[] compiledSources) |
192 { | 163 { |
193 IDictionary<string, string> commandLines = GenerateCommandLinesFromT log(); | 164 IDictionary<string, string> commandLines = GenerateCommandLinesFromT log(); |
194 | 165 |
195 // | 166 // |
196 if (compiledSources != null) | 167 if (compiledSources != null) |
197 { | 168 { |
198 foreach (ITaskItem source in compiledSources) | 169 foreach (ITaskItem source in compiledSources) |
199 { | 170 { |
200 string rmSource = FileTracker.FormatRootingMarker(source); | 171 string rmSource = FileTracker.FormatRootingMarker(source); |
201 commandLines[rmSource] = GenerateCommandLineFromProps(source ) + " " + source.GetMetadata("FullPath").ToUpperInvariant(); | 172 commandLines[rmSource] = TLogCommandForSource(source); |
202 } | 173 } |
203 } | 174 } |
204 | 175 |
205 //write tlog | 176 //write tlog |
206 using (StreamWriter writer = new StreamWriter(this.TLogCommandFile.G etMetadata("FullPath"), false, Encoding.Unicode)) | 177 using (StreamWriter writer = new StreamWriter(this.TLogCommandFile.G etMetadata("FullPath"), false, Encoding.Unicode)) |
207 { | 178 { |
208 foreach (KeyValuePair<string, string> p in commandLines) | 179 foreach (KeyValuePair<string, string> p in commandLines) |
209 { | 180 { |
210 string keyLine = "^" + p.Key; | 181 string keyLine = "^" + p.Key; |
211 writer.WriteLine(keyLine); | 182 writer.WriteLine(keyLine); |
212 writer.WriteLine(p.Value); | 183 writer.WriteLine(p.Value); |
213 } | 184 } |
214 } | 185 } |
215 } | 186 } |
216 | 187 |
217 protected string GenerateCommandLineFromProps(ITaskItem sourceFile, | 188 protected override string GenerateCommandLineForSource(ITaskItem sourceF ile, |
218 bool fullOutputName=false) | 189 bool fullOutputName=false) |
219 { | 190 { |
220 StringBuilder commandLine = new StringBuilder(GCCUtilities.s_Command LineLength); | 191 StringBuilder commandLine = new StringBuilder(GCCUtilities.s_Command LineLength); |
221 | 192 |
222 if (sourceFile != null) | 193 //build command line from components and add required switches |
binji
2013/05/30 23:29:22
sourceFile can't be null now?
Sam Clegg
2013/05/30 23:48:57
I don't think it ever could have been...
| |
194 string props = xamlParser.Parse(sourceFile, fullOutputName); | |
195 commandLine.Append(props); | |
196 commandLine.Append(" -c "); | |
197 | |
198 // Remove rtti items as they are not relevant in C compilation and w ill | |
199 // produce warnings | |
200 if (SourceIsC(sourceFile.ToString())) | |
223 { | 201 { |
224 //build command line from components and add required switches | 202 commandLine.Replace("-fno-rtti", ""); |
225 string props = xamlParser.Parse(sourceFile, fullOutputName); | 203 commandLine.Replace("-frtti", ""); |
226 commandLine.Append(props); | 204 } |
227 commandLine.Append(" -c "); | |
228 | 205 |
229 // Remove rtti items as they are not relevant in C compilation a nd will | 206 if (ConfigurationType == "DynamicLibrary") |
230 // produce warnings | 207 { |
231 if (SourceIsC(sourceFile.ToString())) | 208 commandLine.Append(" -fPIC "); |
232 { | |
233 commandLine.Replace("-fno-rtti", ""); | |
234 commandLine.Replace("-frtti", ""); | |
235 } | |
236 | |
237 if (ConfigurationType == "DynamicLibrary") | |
238 { | |
239 commandLine.Append(" -fPIC "); | |
240 } | |
241 } | 209 } |
242 | 210 |
243 return commandLine.ToString(); | 211 return commandLine.ToString(); |
244 } | 212 } |
245 | 213 |
246 protected ITaskItem[] MergeOutOfDateSources(ITaskItem[] outOfDateSources FromTracking, | |
247 List<ITaskItem> outOfDateSourcesFromCommandLineChanges) | |
248 { | |
249 List<ITaskItem> mergedSources = new List<ITaskItem>(outOfDateSources FromTracking); | |
250 | |
251 foreach (ITaskItem item in outOfDateSourcesFromCommandLineChanges) | |
252 { | |
253 if (!mergedSources.Contains(item)) | |
254 { | |
255 mergedSources.Add(item); | |
256 } | |
257 } | |
258 | |
259 return mergedSources.ToArray(); | |
260 } | |
261 | |
262 private int Compile(string pathToTool) | 214 private int Compile(string pathToTool) |
263 { | 215 { |
264 if (Platform.Equals("pnacl", StringComparison.OrdinalIgnoreCase)) | 216 if (Platform.Equals("pnacl", StringComparison.OrdinalIgnoreCase)) |
265 { | 217 { |
266 if (!SDKUtilities.FindPython()) | 218 if (!SDKUtilities.FindPython()) |
267 { | 219 { |
268 Log.LogError("PNaCl compilation requires python in your exec utable path."); | 220 Log.LogError("PNaCl compilation requires python in your exec utable path."); |
269 return -1; | 221 return -1; |
270 } | 222 } |
271 | 223 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
309 return CompileSerial(pathToTool); | 261 return CompileSerial(pathToTool); |
310 } | 262 } |
311 | 263 |
312 private int CompileSerial(string pathToTool) | 264 private int CompileSerial(string pathToTool) |
313 { | 265 { |
314 int returnCode = 0; | 266 int returnCode = 0; |
315 foreach (ITaskItem sourceItem in CompileSourceList) | 267 foreach (ITaskItem sourceItem in CompileSourceList) |
316 { | 268 { |
317 try | 269 try |
318 { | 270 { |
319 string commandLine = GenerateCommandLineFromProps(sourceItem , true); | 271 string commandLine = GenerateCommandLineForSource(sourceItem , true); |
320 commandLine += GCCUtilities.ConvertPathWindowsToPosix(source Item.ToString()); | 272 commandLine += GCCUtilities.ConvertPathWindowsToPosix(source Item.ToString()); |
321 | 273 |
322 if (OutputCommandLine) | 274 if (OutputCommandLine) |
323 { | 275 { |
324 string logMessage = pathToTool + " " + commandLine; | 276 string logMessage = pathToTool + " " + commandLine; |
325 Log.LogMessage(logMessage); | 277 Log.LogMessage(logMessage); |
326 } | 278 } |
327 else | 279 else |
328 { | 280 { |
329 base.Log.LogMessage(Path.GetFileName(sourceItem.ToString ())); | 281 base.Log.LogMessage(Path.GetFileName(sourceItem.ToString ())); |
(...skipping 19 matching lines...) Expand all Loading... | |
349 private int CompileParallel(string pathToTool) | 301 private int CompileParallel(string pathToTool) |
350 { | 302 { |
351 int returnCode = 0; | 303 int returnCode = 0; |
352 | 304 |
353 // Compute sources that can be compiled together. | 305 // Compute sources that can be compiled together. |
354 Dictionary<string, List<ITaskItem>> srcGroups = | 306 Dictionary<string, List<ITaskItem>> srcGroups = |
355 new Dictionary<string, List<ITaskItem>>(); | 307 new Dictionary<string, List<ITaskItem>>(); |
356 | 308 |
357 foreach (ITaskItem sourceItem in CompileSourceList) | 309 foreach (ITaskItem sourceItem in CompileSourceList) |
358 { | 310 { |
359 string commandLine = GenerateCommandLineFromProps(sourceItem); | 311 string commandLine = GenerateCommandLineForSource(sourceItem); |
360 if (srcGroups.ContainsKey(commandLine)) | 312 if (srcGroups.ContainsKey(commandLine)) |
361 { | 313 { |
362 srcGroups[commandLine].Add(sourceItem); | 314 srcGroups[commandLine].Add(sourceItem); |
363 } | 315 } |
364 else | 316 else |
365 { | 317 { |
366 srcGroups.Add(commandLine, new List<ITaskItem> {sourceItem}) ; | 318 srcGroups.Add(commandLine, new List<ITaskItem> {sourceItem}) ; |
367 } | 319 } |
368 } | 320 } |
369 | 321 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 { | 368 { |
417 returnCode = Compile(pathToTool); | 369 returnCode = Compile(pathToTool); |
418 } | 370 } |
419 finally | 371 finally |
420 { | 372 { |
421 | 373 |
422 } | 374 } |
423 return returnCode; | 375 return returnCode; |
424 } | 376 } |
425 | 377 |
426 protected void CalcSourcesToCompile() | 378 protected override string GenerateResponseFileCommands() |
427 { | 379 { |
428 //check if full recompile is required otherwise perform incremental | 380 return ""; |
429 if (this.ForcedRebuildRequired() || this.MinimalRebuildFromTracking == false) | |
430 { | |
431 this.CompileSourceList = this.Sources; | |
432 return; | |
433 } | |
434 | |
435 //retrieve list of sources out of date due to command line changes | |
436 List<ITaskItem> outOfDateSourcesFromCommandLine = GetOutOfDateSource sFromCmdLineChanges(); | |
437 | |
438 //retrieve sources out of date due to tracking | |
439 CanonicalTrackedOutputFiles trackedOutputFiles = new CanonicalTracke dOutputFiles(this, this.TLogWriteFiles); | |
440 this.TrackedInputFiles = new CanonicalTrackedInputFiles(this, | |
441 this.TLogRea dFiles, | |
442 this.Sources , | |
443 this.Exclude dInputPaths, | |
444 trackedOutpu tFiles, | |
445 true, | |
446 false); | |
447 ITaskItem[] outOfDateSourcesFromTracking = this.TrackedInputFiles.Co mputeSourcesNeedingCompilation(); | |
448 | |
449 //merge out of date lists | |
450 CompileSourceList = MergeOutOfDateSources(outOfDateSourcesFromTracki ng, outOfDateSourcesFromCommandLine); | |
451 | |
452 if (this.CompileSourceList.Length == 0) | |
453 { | |
454 this.SkippedExecution = true; | |
455 return; | |
456 } | |
457 | |
458 //remove sources to compile from tracked file list | |
459 this.TrackedInputFiles.RemoveEntriesForSource(this.CompileSourceList ); | |
460 trackedOutputFiles.RemoveEntriesForSource(this.CompileSourceList); | |
461 this.TrackedInputFiles.SaveTlog(); | |
462 trackedOutputFiles.SaveTlog(); | |
463 } | 381 } |
464 | 382 |
465 protected bool SourceIsC(string sourceFilename) | 383 protected bool SourceIsC(string sourceFilename) |
466 { | 384 { |
467 string fileExt = Path.GetExtension(sourceFilename.ToString()); | 385 string fileExt = Path.GetExtension(sourceFilename.ToString()); |
468 | 386 |
469 if (fileExt == ".c") | 387 if (fileExt == ".c") |
470 return true; | 388 return true; |
471 else | 389 else |
472 return false; | 390 return false; |
473 } | 391 } |
474 | 392 |
475 public override bool Execute() | 393 protected override string CommandTLogFilename |
476 { | |
477 bool returnResult = false; | |
478 | |
479 try | |
480 { | |
481 xamlParser = new XamlParser(PropertiesFile); | |
482 if (!Setup()) | |
483 return false; | |
484 CalcSourcesToCompile(); | |
485 returnResult = base.Execute(); | |
486 } | |
487 finally | |
488 { | |
489 | |
490 } | |
491 | |
492 return returnResult; | |
493 } | |
494 | |
495 protected List<ITaskItem> GetOutOfDateSourcesFromCmdLineChanges() | |
496 { | |
497 //get dictionary of source + command lines | |
498 IDictionary<string, string> dictionary = this.GenerateCommandLinesFr omTlog(); | |
499 List<ITaskItem> outOfDateSources = new List<ITaskItem>(); | |
500 | |
501 //add sources to out of date list if the tlog dictionary string do n ot match the generated command line string | |
502 StringBuilder currentCommandLine = new StringBuilder(GCCUtilities.s_ CommandLineLength); | |
503 foreach (ITaskItem sourceItem in Sources) | |
504 { | |
505 currentCommandLine.Length = 0; | |
506 | |
507 currentCommandLine.Append(GenerateCommandLineFromProps(sourceIte m)); | |
508 currentCommandLine.Append(" "); | |
509 currentCommandLine.Append(sourceItem.GetMetadata("FullPath").ToU pperInvariant()); | |
510 | |
511 string tlogCommandLine = null; | |
512 if (dictionary.TryGetValue(FileTracker.FormatRootingMarker(sourc eItem), out tlogCommandLine)) | |
513 { | |
514 if ((tlogCommandLine == null) || !currentCommandLine.ToStrin g().Equals(tlogCommandLine, StringComparison.Ordinal)) | |
515 { | |
516 outOfDateSources.Add(sourceItem); | |
517 } | |
518 } | |
519 else | |
520 { | |
521 outOfDateSources.Add(sourceItem); | |
522 } | |
523 } | |
524 return outOfDateSources; | |
525 } | |
526 | |
527 [Output] | |
528 public ITaskItem[] CompileSourceList | |
529 { | 394 { |
530 get | 395 get |
531 { | 396 { |
532 return this.compileSourceList; | 397 return BaseTool() + ".compile.command.1.tlog"; |
533 } | |
534 set | |
535 { | |
536 this.compileSourceList = value; | |
537 } | 398 } |
538 } | 399 } |
539 | 400 |
401 protected override string[] ReadTLogFilenames | |
402 { | |
403 get | |
404 { | |
405 return new string[] { BaseTool() + ".compile.read.1.tlog" }; | |
406 } | |
407 } | |
408 | |
409 protected override string WriteTLogFilename | |
410 { | |
411 get | |
412 { | |
413 return BaseTool() + ".compile.write.1.tlog"; | |
414 } | |
415 } | |
416 | |
540 protected override string ToolName | 417 protected override string ToolName |
541 { | 418 { |
542 get | 419 get |
543 { | 420 { |
544 return NaCLCompilerPath; | 421 return NaCLCompilerPath; |
545 } | 422 } |
546 } | 423 } |
547 | 424 |
548 } | 425 } |
549 } | 426 } |
OLD | NEW |