OLD | NEW |
1 | 1 |
2 using System; | 2 using System; |
3 using System.Collections.Generic; | 3 using System.Collections.Generic; |
4 using System.Text; | 4 using System.Text; |
5 using System.Collections; | 5 using System.Collections; |
6 using System.IO; | 6 using System.IO; |
7 using System.Reflection; | 7 using System.Reflection; |
8 using System.Resources; | 8 using System.Resources; |
9 using Microsoft.Build.Framework; | 9 using Microsoft.Build.Framework; |
10 using Microsoft.Build.Utilities; | 10 using Microsoft.Build.Utilities; |
| 11 using System.Collections.Specialized; |
11 | 12 |
12 using System.Diagnostics; | 13 using System.Diagnostics; |
13 | 14 |
14 namespace NaCl.Build.CPPTasks | 15 namespace NaCl.Build.CPPTasks |
15 { | 16 { |
16 public class NaClCompile : ToolTask | 17 public class NaClCompile : ToolTask |
17 { | 18 { |
18 private XamlParser m_XamlParser; | 19 private XamlParser m_XamlParser; |
19 private ITaskItem[] excludedInputPaths; | 20 private ITaskItem[] excludedInputPaths; |
20 private ITaskItem[] tlogReadFiles; | 21 private ITaskItem[] tlogReadFiles; |
(...skipping 11 matching lines...) Expand all Loading... |
32 [Required] | 33 [Required] |
33 public string PropertiesFile { get; set; } | 34 public string PropertiesFile { get; set; } |
34 | 35 |
35 [Required] | 36 [Required] |
36 public ITaskItem[] Sources { get; set; } | 37 public ITaskItem[] Sources { get; set; } |
37 | 38 |
38 [Required] | 39 [Required] |
39 public string NaCLCompilerPath { get; set; } | 40 public string NaCLCompilerPath { get; set; } |
40 | 41 |
41 [Required] | 42 [Required] |
42 public string OutputCommandLine { get; set; } | 43 public bool OutputCommandLine { get; set; } |
| 44 |
| 45 public int ProcessorNumber { get; set; } |
43 | 46 |
44 [Required] | 47 [Required] |
45 public string TrackerLogDirectory { get; set; } | 48 public string TrackerLogDirectory { get; set; } |
46 | 49 |
| 50 protected override StringDictionary EnvironmentOverride |
| 51 { |
| 52 get { |
| 53 string show = OutputCommandLine ? "1" : "0"; |
| 54 string cores = Convert.ToString(ProcessorNumber); |
| 55 return new StringDictionary() { |
| 56 {"NACL_GCC_CORES", cores}, |
| 57 {"NACL_GCC_SHOW_COMMANDS", show } |
| 58 }; |
| 59 } |
| 60 } |
47 | 61 |
48 protected override string GenerateFullPathToTool() { return ToolName; } | 62 protected override string GenerateFullPathToTool() { return ToolName; } |
49 | 63 |
50 public NaClCompile() | 64 public NaClCompile() |
51 : base(new ResourceManager("NaCl.Build.CPPTasks.Properties.Resources
", Assembly.GetExecutingAssembly())) | 65 : base(new ResourceManager("NaCl.Build.CPPTasks.Properties.Resources
", Assembly.GetExecutingAssembly())) |
52 { | 66 { |
53 this.pathToLog = string.Empty; | 67 this.pathToLog = string.Empty; |
54 this.EnvironmentVariables = new string []{"CYGWIN=nodosfilewarning",
"LC_CTYPE=C"}; | 68 this.EnvironmentVariables = new string[] { "CYGWIN=nodosfilewarning"
, "LC_CTYPE=C" }; |
55 } | 69 } |
56 | 70 |
57 protected IDictionary<string, string> GenerateCommandLinesFromTlog() | 71 protected IDictionary<string, string> GenerateCommandLinesFromTlog() |
58 { | 72 { |
59 IDictionary<string, string> cmdLineDictionary = new Dictionary<strin
g, string>(StringComparer.OrdinalIgnoreCase); | 73 IDictionary<string, string> cmdLineDictionary = new Dictionary<strin
g, string>(StringComparer.OrdinalIgnoreCase); |
60 string tlogFilename = this.TLogCommandFile.GetMetadata("FullPath"); | 74 string tlogFilename = this.TLogCommandFile.GetMetadata("FullPath"); |
61 if (File.Exists(tlogFilename)) | 75 if (File.Exists(tlogFilename)) |
62 { | 76 { |
63 using (StreamReader reader = File.OpenText(tlogFilename)) | 77 using (StreamReader reader = File.OpenText(tlogFilename)) |
64 { | 78 { |
65 string filename = string.Empty; | 79 string filename = string.Empty; |
66 for (string lineStr = reader.ReadLine(); lineStr != null; li
neStr = reader.ReadLine()) | 80 for (string lineStr = reader.ReadLine(); lineStr != null; li
neStr = reader.ReadLine()) |
67 { | 81 { |
68 if (lineStr.Length == 0 || | 82 if (lineStr.Length == 0 || |
69 (lineStr[0] == '^' && lineStr.Length == 1)) | 83 (lineStr[0] == '^' && lineStr.Length == 1)) |
70 { | 84 { |
71 Log.LogMessage(MessageImportance.High, "Invalid line
in command tlog"); | 85 Log.LogError("Invalid line in command tlog"); |
72 break; | 86 break; |
73 } | 87 } |
74 else if (lineStr[0] == '^') | 88 else if (lineStr[0] == '^') |
75 { | 89 { |
76 filename = lineStr.Substring(1); | 90 filename = lineStr.Substring(1); |
77 } | 91 } |
78 else | 92 else |
79 { | 93 { |
80 cmdLineDictionary[filename] = lineStr; | 94 cmdLineDictionary[filename] = lineStr; |
81 } | 95 } |
82 } | 96 } |
83 } | 97 } |
84 } | 98 } |
85 return cmdLineDictionary; | 99 return cmdLineDictionary; |
86 } | 100 } |
87 | 101 |
88 protected override void LogEventsFromTextOutput(string singleLine, Messa
geImportance messageImportance) | 102 protected override void LogEventsFromTextOutput(string singleLine, Messa
geImportance messageImportance) |
89 { | 103 { |
90 base.LogEventsFromTextOutput(GCCUtilities.Convert_Output_GCC_to_VS(s
ingleLine), messageImportance); | 104 base.LogEventsFromTextOutput(GCCUtilities.ConvertGCCOutput(singleLin
e), messageImportance); |
| 105 } |
| 106 |
| 107 static string GetObjectFile(ITaskItem source) |
| 108 { |
| 109 string objectFilePath = Path.GetFullPath(source.GetMetadata("ObjectF
ileName")); |
| 110 // cl.exe will accept a folder name as the ObjectFileName in which c
ase |
| 111 // the objectfile is created as <ObjectFileName>/<basename>.obj. He
re |
| 112 // we mimic this behaviour. |
| 113 if ((File.GetAttributes(objectFilePath) & FileAttributes.Directory)
!= 0) |
| 114 { |
| 115 objectFilePath = Path.Combine(objectFilePath, Path.GetFileName(s
ource.ItemSpec)); |
| 116 objectFilePath = Path.ChangeExtension(objectFilePath, ".obj"); |
| 117 } |
| 118 return objectFilePath; |
91 } | 119 } |
92 | 120 |
93 private void ConstructReadTLog(ITaskItem[] compiledSources, CanonicalTra
ckedOutputFiles outputs) | 121 private void ConstructReadTLog(ITaskItem[] compiledSources, CanonicalTra
ckedOutputFiles outputs) |
94 { | 122 { |
95 string trackerPath = Path.GetFullPath(TlogDirectory + ReadTLogFilena
mes[0]); | 123 string trackerPath = Path.GetFullPath(TlogDirectory + ReadTLogFilena
mes[0]); |
96 | 124 |
97 //save tlog for sources not compiled during this execution | 125 //save tlog for sources not compiled during this execution |
98 TaskItem readTrackerItem = new TaskItem(trackerPath); | 126 TaskItem readTrackerItem = new TaskItem(trackerPath); |
99 CanonicalTrackedInputFiles files = new CanonicalTrackedInputFiles(ne
w TaskItem[] { readTrackerItem }, Sources, outputs, false, false); | 127 CanonicalTrackedInputFiles files = new CanonicalTrackedInputFiles(ne
w TaskItem[] { readTrackerItem }, Sources, outputs, false, false); |
100 files.RemoveEntriesForSource(compiledSources); | 128 files.RemoveEntriesForSource(compiledSources); |
101 files.SaveTlog(); | 129 files.SaveTlog(); |
102 | 130 |
103 //add tlog information for compiled sources | 131 //add tlog information for compiled sources |
104 using (StreamWriter writer = new StreamWriter(trackerPath, true, Enc
oding.Unicode)) | 132 using (StreamWriter writer = new StreamWriter(trackerPath, true, Enc
oding.Unicode)) |
105 { | 133 { |
106 foreach (ITaskItem source in compiledSources) | 134 foreach (ITaskItem source in compiledSources) |
107 { | 135 { |
108 string sourcePath = Path.GetFullPath(source.ItemSpec).ToUppe
rInvariant(); | 136 string sourcePath = Path.GetFullPath(source.ItemSpec).ToUppe
rInvariant(); |
109 | 137 string objectFilePath = GetObjectFile(source); |
110 string objectFilePath = Path.GetFullPath(source.GetMetadata(
"ObjectFileName")); | |
111 string depFilePath = Path.ChangeExtension(objectFilePath, ".
d"); | 138 string depFilePath = Path.ChangeExtension(objectFilePath, ".
d"); |
112 | 139 |
113 try | 140 try |
114 { | 141 { |
115 if (File.Exists(depFilePath) == false) | 142 if (File.Exists(depFilePath) == false) |
116 { | 143 { |
117 Log.LogMessage(MessageImportance.High, depFilePath +
" not found"); | 144 Log.LogMessage(MessageImportance.High, depFilePath +
" not found"); |
118 } | 145 } |
119 else | 146 else |
120 { | 147 { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 } | 229 } |
203 } | 230 } |
204 } | 231 } |
205 | 232 |
206 protected string GenerateCommandLineFromProps(ITaskItem sourceFile) | 233 protected string GenerateCommandLineFromProps(ITaskItem sourceFile) |
207 { | 234 { |
208 StringBuilder commandLine = new StringBuilder(GCCUtilities.s_Command
LineLength); | 235 StringBuilder commandLine = new StringBuilder(GCCUtilities.s_Command
LineLength); |
209 | 236 |
210 if (sourceFile != null) | 237 if (sourceFile != null) |
211 { | 238 { |
212 string sourcePath = GCCUtilities.Convert_Path_Windows_To_Posix(s
ourceFile.ToString()); | |
213 | |
214 // Remove rtti items as they are not relevant in C compilation a
nd will produce warnings | 239 // Remove rtti items as they are not relevant in C compilation a
nd will produce warnings |
215 if (SourceIsC(sourceFile.ToString())) | 240 if (SourceIsC(sourceFile.ToString())) |
216 { | 241 { |
217 commandLine.Replace("-fno-rtti", ""); | 242 commandLine.Replace("-fno-rtti", ""); |
218 commandLine.Replace("-frtti", ""); | 243 commandLine.Replace("-frtti", ""); |
219 } | 244 } |
220 | 245 |
221 //build command line from components and add required switches | 246 //build command line from components and add required switches |
222 string props = m_XamlParser.Parse(sourceFile); | 247 string props = m_XamlParser.Parse(sourceFile); |
223 commandLine.Append(props); | 248 commandLine.Append(props); |
224 commandLine.Append(" -MD -c "); | 249 commandLine.Append(" -MD -c "); |
225 commandLine.Append("\"" + sourcePath + "\""); | |
226 } | 250 } |
227 | 251 |
228 return commandLine.ToString(); | 252 return commandLine.ToString(); |
229 } | 253 } |
230 | 254 |
231 protected ITaskItem[] MergeOutOfDateSources(ITaskItem[] outOfDateSources
FromTracking, List<ITaskItem> outOfDateSourcesFromCommandLineChanges) | 255 protected ITaskItem[] MergeOutOfDateSources(ITaskItem[] outOfDateSources
FromTracking, List<ITaskItem> outOfDateSourcesFromCommandLineChanges) |
232 { | 256 { |
233 List<ITaskItem> mergedSources = new List<ITaskItem>(outOfDateSources
FromTracking); | 257 List<ITaskItem> mergedSources = new List<ITaskItem>(outOfDateSources
FromTracking); |
234 | 258 |
235 foreach (ITaskItem item in outOfDateSourcesFromCommandLineChanges) | 259 foreach (ITaskItem item in outOfDateSourcesFromCommandLineChanges) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 else | 291 else |
268 { | 292 { |
269 return false; | 293 return false; |
270 } | 294 } |
271 } | 295 } |
272 | 296 |
273 private int Compile(string pathToTool) | 297 private int Compile(string pathToTool) |
274 { | 298 { |
275 int returnCode = 0; | 299 int returnCode = 0; |
276 | 300 |
277 foreach (ITaskItem sourceFileItem in CompileSourceList) | 301 // Compute sources that can be compiled together. |
| 302 Dictionary<string, List<ITaskItem>> srcGroups = |
| 303 new Dictionary<string, List<ITaskItem>>(); |
| 304 |
| 305 foreach (ITaskItem sourceItem in CompileSourceList) |
278 { | 306 { |
| 307 string commandLine = GenerateCommandLineFromProps(sourceItem); |
| 308 if (srcGroups.ContainsKey(commandLine)) |
| 309 { |
| 310 srcGroups[commandLine].Add(sourceItem); |
| 311 } |
| 312 else |
| 313 { |
| 314 srcGroups.Add(commandLine, new List<ITaskItem> {sourceItem})
; |
| 315 } |
| 316 } |
| 317 |
| 318 string pythonExe = "C:\\python_26_amd64\\files\\python.exe"; |
| 319 string pythonScript = Path.GetDirectoryName(Path.GetDirectoryName(Pr
opertiesFile)); |
| 320 pythonScript = Path.Combine(pythonScript, "compiler_wrapper.py"); |
| 321 |
| 322 foreach (KeyValuePair<string, List<ITaskItem>> entry in srcGroups) |
| 323 { |
| 324 string commandLine = entry.Key; |
| 325 string cmd = "\"" + pathToTool + "\" " + commandLine + "--"; |
| 326 List<ITaskItem> sources = entry.Value; |
| 327 |
| 328 foreach (ITaskItem sourceItem in sources) |
| 329 { |
| 330 string src = GCCUtilities.ConvertPathWindowsToPosix(sourceIt
em.ToString()); |
| 331 cmd += " \"" + src + "\""; |
| 332 } |
| 333 |
279 try | 334 try |
280 { | 335 { |
281 string commandLine = GenerateCommandLineFromProps(sourceFile
Item); | 336 // compile this group of sources |
282 | 337 returnCode = base.ExecuteTool(pythonExe, cmd, "\"" + pythonS
cript + "\""); |
283 base.Log.LogMessageFromText(Path.GetFileName(sourceFileItem.
ToString()), MessageImportance.High); | |
284 | |
285 if (OutputCommandLine == "true") | |
286 { | |
287 string logMessage = pathToTool + " " + commandLine; | |
288 Log.LogMessageFromText(logMessage, MessageImportance.Hig
h); | |
289 } | |
290 | |
291 | |
292 // compile | |
293 returnCode = base.ExecuteTool(pathToTool, commandLine, strin
g.Empty); | |
294 } | 338 } |
295 catch (Exception) | 339 catch (Exception e) |
296 { | 340 { |
| 341 Log.LogMessage("compiler exception: {0}", e); |
297 returnCode = base.ExitCode; | 342 returnCode = base.ExitCode; |
298 } | 343 } |
299 | 344 |
300 //abort if an error was encountered | 345 //abort if an error was encountered |
301 if (returnCode != 0) | 346 if (returnCode != 0) |
302 { | 347 break; |
303 return returnCode; | |
304 } | |
305 } | 348 } |
| 349 |
| 350 Log.LogMessage(MessageImportance.Low, "compiler returned: {0}", retu
rnCode); |
306 return returnCode; | 351 return returnCode; |
307 } | 352 } |
308 | 353 |
309 protected override int ExecuteTool(string pathToTool, string responseFil
eCommands, string commandLineCommands) | 354 protected override int ExecuteTool(string pathToTool, string responseFil
eCommands, string commandLineCommands) |
310 { | 355 { |
311 if (File.Exists(pathToTool) == false) | 356 if (File.Exists(pathToTool) == false) |
312 { | 357 { |
313 base.Log.LogMessageFromText("Unable to find NaCL compiler: " + p
athToTool, MessageImportance.High); | 358 base.Log.LogMessageFromText("Unable to find NaCL compiler: " + p
athToTool, MessageImportance.High); |
314 return -1; | 359 return -1; |
315 } | 360 } |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 | 680 |
636 protected override Encoding ResponseFileEncoding | 681 protected override Encoding ResponseFileEncoding |
637 { | 682 { |
638 get | 683 get |
639 { | 684 { |
640 return Encoding.ASCII; | 685 return Encoding.ASCII; |
641 } | 686 } |
642 } | 687 } |
643 } | 688 } |
644 } | 689 } |
OLD | NEW |