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 | |
binji
2012/10/29 18:08:59
nit: comment fits on one line?
Sam Clegg
2012/10/29 22:42:51
Done.
| |
20 /// the translator 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 | |
26 /// the translator 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 | |
32 /// the translator 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 = new CanonicalTrackedOutpu tFiles(new TaskItem[] { item }); | |
binji
2012/10/29 18:08:59
nit: wrap at 100, here and elsewhere
Sam Clegg
2012/10/29 22:42:51
Done.
| |
59 | |
60 foreach (ITaskItem sourceItem in Sources) | |
61 { | |
62 //remove this entry associated with compiled source which is abo ut to be recomputed | |
63 trackedFiles.RemoveEntriesForSource(sourceItem); | |
64 | |
65 //add entry with updated information | |
66 trackedFiles.AddComputedOutputForSourceRoot(Path.GetFullPath(sou rceItem.ItemSpec).ToUpperInvariant(), | |
67 OutputFile); | |
68 } | |
69 | |
70 //output tlog | |
71 trackedFiles.SaveTlog(); | |
72 | |
73 return trackedFiles; | |
74 } | |
75 | |
76 protected override void OutputReadTLog(ITaskItem[] compiledSources, Cano nicalTrackedOutputFiles outputs) | |
77 { | |
78 string trackerPath = Path.GetFullPath(TlogDirectory + ReadTLogFilena mes[0]); | |
79 | |
80 using (StreamWriter writer = new StreamWriter(trackerPath, false, En coding.Unicode)) | |
81 { | |
82 string sourcePath = ""; | |
83 foreach (ITaskItem source in Sources) | |
84 { | |
85 if (sourcePath != "") | |
86 sourcePath += "|"; | |
87 sourcePath += Path.GetFullPath(source.ItemSpec).ToUpperInvar iant(); | |
88 } | |
89 | |
90 writer.WriteLine("^" + sourcePath); | |
91 foreach (ITaskItem source in Sources) | |
92 { | |
93 writer.WriteLine(Path.GetFullPath(source.ItemSpec).ToUpperIn variant()); | |
94 } | |
95 writer.WriteLine(Path.GetFullPath(OutputFile).ToUpperInvariant() ); | |
96 } | |
97 } | |
98 | |
99 protected override void OutputCommandTLog(ITaskItem[] compiledSources) | |
100 { | |
101 //write tlog | |
binji
2012/10/29 18:08:59
nit: remove unnecessary comment
Sam Clegg
2012/10/29 22:42:51
Done.
| |
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")) |
binji
2012/10/29 18:08:59
maybe should only try translating when platform is
Sam Clegg
2012/10/29 22:42:51
None of the other platforms will set these Transla
binji
2012/10/29 23:14:02
Probably not a big deal -- I was just thinking you
| |
189 return false; | |
190 | |
191 if (TranslateX86 == "true" && !Translate("x86-32")) | |
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 |