| OLD | NEW |
| 1 | 1 |
| 2 using System; | 2 using System; |
| 3 using System.IO; | 3 using System.IO; |
| 4 using System.Resources; | 4 using System.Resources; |
| 5 using System.Reflection; | 5 using System.Reflection; |
| 6 using System.Text; | 6 using System.Text; |
| 7 using Microsoft.Build.Framework; | 7 using Microsoft.Build.Framework; |
| 8 using Microsoft.Build.CPPTasks; | 8 using Microsoft.Build.CPPTasks; |
| 9 using Microsoft.Build.Utilities; |
| 9 | 10 |
| 10 | 11 |
| 11 namespace NaCl.Build.CPPTasks | 12 namespace NaCl.Build.CPPTasks |
| 12 { | 13 { |
| 13 public class NaClLink : TrackedVCToolTask | 14 public class NaClLink : NaClToolTask |
| 14 » { | 15 { |
| 15 private XamlParser m_XamlParser; | 16 public bool BuildingInIDE { get; set; } |
| 16 | 17 |
| 17 public bool BuildingInIDE { get; set; } | 18 /// <summary> |
| 19 /// Property set only in PNaCl builds to signal that the translator |
| 20 /// should be run post-link. |
| 21 /// </summary> |
| 22 public string TranslateARM { get; set; } |
| 23 |
| 24 /// <summary> |
| 25 /// Property set only in PNaCl builds to signal that the translator |
| 26 /// should be run post-link. |
| 27 /// </summary> |
| 28 public string TranslateX86 { get; set; } |
| 29 |
| 30 /// <summary> |
| 31 /// Property set only in PNaCl builds to signal that the translator |
| 32 /// should be run post-link. |
| 33 /// </summary> |
| 34 public string TranslateX64 { get; set; } |
| 18 | 35 |
| 19 [Required] | 36 [Required] |
| 20 public string OutputCommandLine { get; set; } | 37 public string OutputCommandLine { get; set; } |
| 21 | 38 |
| 22 [Required] | 39 [Required] |
| 23 public string NaClLinkerPath { get; set; } | 40 public string NaClLinkerPath { get; set; } |
| 24 | 41 |
| 25 [Required] | 42 [Required] |
| 43 public string Platform { get; set; } |
| 44 |
| 45 [Required] |
| 26 public virtual string OutputFile { get; set; } | 46 public virtual string OutputFile { get; set; } |
| 27 | 47 |
| 28 [Required] | 48 [Required] |
| 29 public string PropertiesFile { get; set; } | 49 public string PropertiesFile { get; set; } |
| 30 | 50 |
| 31 [Required] | 51 [Required] |
| 32 public virtual ITaskItem[] Sources { get; set; } | 52 public string ConfigurationType { get; set; } |
| 33 | 53 |
| 34 [Required] | 54 protected override CanonicalTrackedOutputFiles OutputWriteTLog(ITaskItem
[] inputs) |
| 35 public string ConfigurationType { get; set; } | 55 { |
| 56 string path = Path.Combine(TlogDirectory, WriteTLogFilename); |
| 57 TaskItem item = new TaskItem(path); |
| 58 CanonicalTrackedOutputFiles trackedFiles = |
| 59 new CanonicalTrackedOutputFiles(new TaskItem[] { item }); |
| 60 |
| 61 foreach (ITaskItem sourceItem in Sources) |
| 62 { |
| 63 //remove this entry associated with compiled source which is abo
ut to be recomputed |
| 64 trackedFiles.RemoveEntriesForSource(sourceItem); |
| 65 |
| 66 //add entry with updated information |
| 67 string upper = Path.GetFullPath(sourceItem.ItemSpec).ToUpperInva
riant(); |
| 68 trackedFiles.AddComputedOutputForSourceRoot(upper, OutputFile); |
| 69 } |
| 70 |
| 71 //output tlog |
| 72 trackedFiles.SaveTlog(); |
| 73 |
| 74 return trackedFiles; |
| 75 } |
| 76 |
| 77 protected override void OutputReadTLog(ITaskItem[] compiledSources, Cano
nicalTrackedOutputFiles outputs) |
| 78 { |
| 79 string trackerPath = Path.GetFullPath(TlogDirectory + ReadTLogFilena
mes[0]); |
| 80 |
| 81 using (StreamWriter writer = new StreamWriter(trackerPath, false, En
coding.Unicode)) |
| 82 { |
| 83 string sourcePath = ""; |
| 84 foreach (ITaskItem source in Sources) |
| 85 { |
| 86 if (sourcePath != "") |
| 87 sourcePath += "|"; |
| 88 sourcePath += Path.GetFullPath(source.ItemSpec).ToUpperInvar
iant(); |
| 89 } |
| 90 |
| 91 writer.WriteLine("^" + sourcePath); |
| 92 foreach (ITaskItem source in Sources) |
| 93 { |
| 94 writer.WriteLine(Path.GetFullPath(source.ItemSpec).ToUpperIn
variant()); |
| 95 } |
| 96 writer.WriteLine(Path.GetFullPath(OutputFile).ToUpperInvariant()
); |
| 97 } |
| 98 } |
| 99 |
| 100 protected override void OutputCommandTLog(ITaskItem[] compiledSources) |
| 101 { |
| 102 using (StreamWriter writer = new StreamWriter(TLogCommandFile.GetMet
adata("FullPath"), false, Encoding.Unicode)) |
| 103 { |
| 104 string cmds = GenerateResponseFileCommands(); |
| 105 string sourcePath = ""; |
| 106 foreach (ITaskItem source in Sources) |
| 107 { |
| 108 if (sourcePath != "") |
| 109 sourcePath += "|"; |
| 110 sourcePath += Path.GetFullPath(source.ItemSpec).ToUpperInvar
iant(); |
| 111 } |
| 112 |
| 113 writer.WriteLine("^" + sourcePath); |
| 114 writer.WriteLine(cmds); |
| 115 } |
| 116 } |
| 36 | 117 |
| 37 public NaClLink() | 118 public NaClLink() |
| 38 : base(new ResourceManager("NaCl.Build.CPPTasks.Properties.Resources
", Assembly.GetExecutingAssembly())) | 119 : base(new ResourceManager("NaCl.Build.CPPTasks.Properties.Resources
", Assembly.GetExecutingAssembly())) |
| 39 { | 120 { |
| 40 this.EnvironmentVariables = new string[] { "CYGWIN=nodosfilewarning",
"LC_CTYPE=C" }; | 121 this.EnvironmentVariables = new string[] { "CYGWIN=nodosfilewarning"
, "LC_CTYPE=C" }; |
| 41 } | |
| 42 | |
| 43 protected override string CommandTLogName | |
| 44 { | |
| 45 get | |
| 46 { | |
| 47 return "default.link.command.tlog"; | |
| 48 } | |
| 49 } | |
| 50 | |
| 51 protected override string[] ReadTLogNames | |
| 52 { | |
| 53 get | |
| 54 { | |
| 55 return new string[] { | |
| 56 "default.link.read.tlog" | |
| 57 }; | |
| 58 } | |
| 59 } | |
| 60 | |
| 61 protected override string[] WriteTLogNames | |
| 62 { | |
| 63 get | |
| 64 { | |
| 65 return new string[] { | |
| 66 "default.link.write.tlog" | |
| 67 }; | |
| 68 } | |
| 69 } | 122 } |
| 70 | 123 |
| 71 protected override void LogEventsFromTextOutput(string singleLine, Messa
geImportance messageImportance) | 124 protected override void LogEventsFromTextOutput(string singleLine, Messa
geImportance messageImportance) |
| 72 { | 125 { |
| 73 base.LogEventsFromTextOutput(GCCUtilities.ConvertGCCOutput(singleLin
e), messageImportance); | 126 base.LogEventsFromTextOutput(GCCUtilities.ConvertGCCOutput(singleLin
e), messageImportance); |
| 74 } | 127 } |
| 75 | 128 |
| 76 protected override string GenerateResponseFileCommands() | 129 protected override string GenerateResponseFileCommands() |
| 77 { | 130 { |
| 78 StringBuilder responseFileCmds = new StringBuilder(GCCUtilities.s_Co
mmandLineLength); | 131 StringBuilder responseFileCmds = new StringBuilder(GCCUtilities.s_Co
mmandLineLength); |
| 79 | 132 |
| 80 // We want GCC to behave more like visual studio in term of library
dependencies | 133 // We want GCC to behave more like visual studio in term of library
dependencies |
| 81 // so we wrap all the inputs (libraries and object) into one group s
o they are | 134 // so we wrap all the inputs (libraries and object) into one group s
o they are |
| 82 // searched iteratively. | 135 // searched iteratively. |
| 83 responseFileCmds.Append("-Wl,--start-group "); | 136 responseFileCmds.Append("-Wl,--start-group "); |
| 84 foreach (ITaskItem sourceFile in Sources) | 137 foreach (ITaskItem sourceFile in Sources) |
| 85 { | 138 { |
| 86 responseFileCmds.Append(GCCUtilities.ConvertPathWindowsToPosix(s
ourceFile.GetMetadata("Identity"))); | 139 responseFileCmds.Append(GCCUtilities.ConvertPathWindowsToPosix(s
ourceFile.GetMetadata("Identity"))); |
| 87 responseFileCmds.Append(" "); | 140 responseFileCmds.Append(" "); |
| 88 } | 141 } |
| 89 responseFileCmds.Append("-Wl,--end-group "); | 142 responseFileCmds.Append("-Wl,--end-group "); |
| 90 | 143 |
| 91 responseFileCmds.Append(m_XamlParser.Parse(Sources[0], false)); | 144 responseFileCmds.Append(xamlParser.Parse(Sources[0], false)); |
| 92 | 145 |
| 93 return responseFileCmds.ToString(); | 146 return responseFileCmds.ToString(); |
| 94 } | 147 } |
| 95 | 148 |
| 149 private bool Translate(string arch) |
| 150 { |
| 151 string nexeBase = Path.GetFileNameWithoutExtension(OutputFile) + "_"
+ arch + ".nexe"; |
| 152 string outfile = Path.Combine(Path.GetDirectoryName(OutputFile), nex
eBase); |
| 153 |
| 154 string commandLineCommands = String.Format("-arch {0} \"{1}\" -o \"{
2}\"", arch, OutputFile, outfile); |
| 155 |
| 156 string translateTool = Path.Combine(Path.GetDirectoryName(GenerateFu
llPathToTool()), "pnacl-translate.bat"); |
| 157 if (OutputCommandLine != "true") |
| 158 Log.LogMessage("pnacl-translate {0}", Path.GetFileName(nexeBase)
); |
| 159 |
| 160 if (ExecuteTool(translateTool, commandLineCommands, string.Empty) !=
0) |
| 161 { |
| 162 return false; |
| 163 } |
| 164 |
| 165 return true; |
| 166 } |
| 167 |
| 96 public override bool Execute() | 168 public override bool Execute() |
| 97 { | 169 { |
| 170 if (Platform.Equals("pnacl", StringComparison.OrdinalIgnoreCase)) |
| 171 { |
| 172 if (!GCCUtilities.FindPython()) |
| 173 { |
| 174 Log.LogError("PNaCl linking requires python in your executab
le path."); |
| 175 return false; |
| 176 } |
| 177 } |
| 178 |
| 98 bool returnResult = false; | 179 bool returnResult = false; |
| 99 | 180 |
| 100 try | 181 try |
| 101 { | 182 { |
| 102 m_XamlParser = new XamlParser(PropertiesFile); | 183 xamlParser = new XamlParser(PropertiesFile); |
| 184 if (!Setup()) |
| 185 return false; |
| 186 returnResult = base.Execute(); |
| 103 | 187 |
| 104 returnResult = base.Execute(); | 188 if (TranslateX64 == "true" && !Translate("x86_64")) |
| 189 return false; |
| 190 |
| 191 if (TranslateX86 == "true" && !Translate("i686")) |
| 192 return false; |
| 193 |
| 194 if (TranslateARM == "true" && !Translate("arm")) |
| 195 return false; |
| 105 } | 196 } |
| 106 finally | 197 finally |
| 107 { | 198 { |
| 108 | 199 |
| 109 } | 200 } |
| 110 | 201 |
| 111 return returnResult; | 202 return returnResult; |
| 112 } | 203 } |
| 113 | 204 |
| 114 protected override int ExecuteTool(string pathToTool, string responseFil
eCommands, string commandLineCommands) | 205 protected override int ExecuteTool(string pathToTool, string responseFil
eCommands, string commandLineCommands) |
| 115 { | 206 { |
| 116 if (OutputCommandLine == "true") | 207 if (OutputCommandLine == "true") |
| 117 { | 208 { |
| 118 Log.LogMessage(MessageImportance.High, pathToTool + " " + respo
nseFileCommands); | 209 Log.LogMessage(MessageImportance.High, pathToTool + " " + respo
nseFileCommands); |
| 119 } | 210 } |
| 120 | 211 |
| 121 return base.ExecuteTool(pathToTool, responseFileCommands, commandLin
eCommands); | 212 return base.ExecuteTool(pathToTool, responseFileCommands, commandLin
eCommands); |
| 122 } | 213 } |
| 123 | 214 |
| 124 protected override void PostProcessSwitchList() | |
| 125 { | |
| 126 //skip default behavior | |
| 127 } | |
| 128 | |
| 129 protected override string GenerateFullPathToTool() | 215 protected override string GenerateFullPathToTool() |
| 130 { | 216 { |
| 131 return this.ToolName; | 217 return this.ToolName; |
| 132 } | 218 } |
| 133 | 219 |
| 134 protected override string TrackerIntermediateDirectory | |
| 135 { | |
| 136 get | |
| 137 { | |
| 138 if (this.TrackerLogDirectory != null) | |
| 139 { | |
| 140 return this.TrackerLogDirectory; | |
| 141 } | |
| 142 | |
| 143 return string.Empty; | |
| 144 } | |
| 145 } | |
| 146 | |
| 147 protected override Encoding ResponseFileEncoding | 220 protected override Encoding ResponseFileEncoding |
| 148 { | 221 { |
| 149 get | 222 get |
| 150 { | 223 { |
| 151 return Encoding.ASCII; | 224 return Encoding.ASCII; |
| 152 } | 225 } |
| 153 } | 226 } |
| 154 | 227 |
| 155 protected override ITaskItem[] TrackedInputFiles | |
| 156 { | |
| 157 get | |
| 158 { | |
| 159 return this.Sources; | |
| 160 } | |
| 161 } | |
| 162 | |
| 163 protected override bool MaintainCompositeRootingMarkers | |
| 164 { | |
| 165 get | |
| 166 { | |
| 167 return true; | |
| 168 } | |
| 169 | |
| 170 } | |
| 171 | |
| 172 protected override string ToolName | 228 protected override string ToolName |
| 173 { | 229 { |
| 174 get | 230 get |
| 175 { | 231 { |
| 176 return NaClLinkerPath; | 232 return NaClLinkerPath; |
| 177 } | 233 } |
| 178 } | 234 } |
| 179 | 235 |
| 180 public override bool AttributeFileTracking | 236 protected override string CommandTLogFilename |
| 181 { | 237 { |
| 182 get | 238 get |
| 183 { | 239 { |
| 184 return true; | 240 return BaseTool() + ".link.command.1.tlog"; |
| 185 } | 241 } |
| 186 } | 242 } |
| 243 |
| 244 protected override string[] ReadTLogFilenames |
| 245 { |
| 246 get |
| 247 { |
| 248 return new string[] { BaseTool() + ".link.read.1.tlog" }; |
| 249 } |
| 250 } |
| 251 |
| 252 protected override string WriteTLogFilename |
| 253 { |
| 254 get |
| 255 { |
| 256 return BaseTool() + ".link.write.1.tlog"; |
| 257 } |
| 258 } |
| 187 | 259 |
| 188 public virtual string PlatformToolset | 260 public virtual string PlatformToolset |
| 189 { | 261 { |
| 190 get | 262 get |
| 191 { | 263 { |
| 192 return "GCC"; | 264 return "GCC"; |
| 193 } | 265 } |
| 194 set | 266 set |
| 195 {} | 267 {} |
| 196 } | 268 } |
| 197 | 269 } |
| 198 public string TrackerLogDirectory { get; set; } | |
| 199 » } | |
| 200 } | 270 } |
| OLD | NEW |