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 |