corrade-vassal – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | vero | 1 | #region BSD License |
2 | /* |
||
3 | Copyright (c) 2004 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehead (dan05a@gmail.com) |
||
4 | |||
5 | Redistribution and use in source and binary forms, with or without modification, are permitted |
||
6 | provided that the following conditions are met: |
||
7 | |||
8 | * Redistributions of source code must retain the above copyright notice, this list of conditions |
||
9 | and the following disclaimer. |
||
10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions |
||
11 | and the following disclaimer in the documentation and/or other materials provided with the |
||
12 | distribution. |
||
13 | * The name of the author may not be used to endorse or promote products derived from this software |
||
14 | without specific prior written permission. |
||
15 | |||
16 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, |
||
17 | BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||
19 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
||
20 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
||
21 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
||
22 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
23 | */ |
||
24 | #endregion |
||
25 | |||
26 | #region CVS Information |
||
27 | /* |
||
28 | * $Source$ |
||
29 | * $Author: dmoonfire $ |
||
30 | * $Date: 2008-12-14 13:35:55 -0800 (Sun, 14 Dec 2008) $ |
||
31 | * $Revision: 283 $ |
||
32 | */ |
||
33 | #endregion |
||
34 | |||
35 | using System; |
||
36 | using System.Collections; |
||
37 | using System.Collections.Specialized; |
||
38 | using System.IO; |
||
39 | using System.Reflection; |
||
40 | using System.Text.RegularExpressions; |
||
41 | |||
42 | using Prebuild.Core.Attributes; |
||
43 | using Prebuild.Core.Interfaces; |
||
44 | using Prebuild.Core.Nodes; |
||
45 | using Prebuild.Core.Utilities; |
||
46 | |||
47 | namespace Prebuild.Core.Targets |
||
48 | { |
||
49 | /// <summary> |
||
50 | /// |
||
51 | /// </summary> |
||
52 | [Target("monodev")] |
||
53 | public class MonoDevelopTarget : ITarget |
||
54 | { |
||
55 | #region Fields |
||
56 | |||
57 | private Kernel m_Kernel; |
||
58 | |||
59 | #endregion |
||
60 | |||
61 | #region Private Methods |
||
62 | |||
63 | private static string PrependPath(string path) |
||
64 | { |
||
65 | string tmpPath = Helper.NormalizePath(path, '/'); |
||
66 | Regex regex = new Regex(@"(\w):/(\w+)"); |
||
67 | Match match = regex.Match(tmpPath); |
||
68 | if(match.Success || tmpPath[0] == '.' || tmpPath[0] == '/') |
||
69 | { |
||
70 | tmpPath = Helper.NormalizePath(tmpPath); |
||
71 | } |
||
72 | else |
||
73 | { |
||
74 | tmpPath = Helper.NormalizePath("./" + tmpPath); |
||
75 | } |
||
76 | |||
77 | return tmpPath; |
||
78 | } |
||
79 | |||
80 | private static string BuildReference(SolutionNode solution, ReferenceNode refr) |
||
81 | { |
||
82 | string ret = "<ProjectReference type=\""; |
||
83 | if(solution.ProjectsTable.ContainsKey(refr.Name)) |
||
84 | { |
||
85 | ret += "Project\""; |
||
86 | ret += " localcopy=\"" + refr.LocalCopy.ToString() + "\" refto=\"" + refr.Name + "\" />"; |
||
87 | } |
||
88 | else |
||
89 | { |
||
90 | ProjectNode project = (ProjectNode)refr.Parent; |
||
91 | string fileRef = FindFileReference(refr.Name, project); |
||
92 | |||
93 | if(refr.Path != null || fileRef != null) |
||
94 | { |
||
95 | ret += "Assembly\" refto=\""; |
||
96 | |||
97 | string finalPath = (refr.Path != null) ? Helper.MakeFilePath(refr.Path, refr.Name, "dll") : fileRef; |
||
98 | |||
99 | ret += finalPath; |
||
100 | ret += "\" localcopy=\"" + refr.LocalCopy.ToString() + "\" />"; |
||
101 | return ret; |
||
102 | } |
||
103 | |||
104 | ret += "Gac\""; |
||
105 | ret += " localcopy=\"" + refr.LocalCopy.ToString() + "\""; |
||
106 | ret += " refto=\""; |
||
107 | try |
||
108 | { |
||
109 | /* |
||
110 | Day changed to 28 Mar 2007 |
||
111 | ... |
||
112 | 08:09 < cj> is there anything that replaces Assembly.LoadFromPartialName() ? |
||
113 | 08:09 < jonp> no |
||
114 | 08:10 < jonp> in their infinite wisdom [sic], microsoft decided that the |
||
115 | ability to load any assembly version by-name was an inherently |
||
116 | bad idea |
||
117 | 08:11 < cj> I'm thinking of a bunch of four-letter words right now... |
||
118 | 08:11 < cj> security through making it difficult for the developer!!! |
||
119 | 08:12 < jonp> just use the Obsolete API |
||
120 | 08:12 < jonp> it should still work |
||
121 | 08:12 < cj> alrighty. |
||
122 | 08:12 < jonp> you just get warnings when using it |
||
123 | */ |
||
124 | Assembly assem = Assembly.LoadWithPartialName(refr.Name); |
||
125 | ret += assem.FullName; |
||
126 | //ret += refr.Name; |
||
127 | } |
||
128 | catch (System.NullReferenceException e) |
||
129 | { |
||
130 | e.ToString(); |
||
131 | ret += refr.Name; |
||
132 | } |
||
133 | ret += "\" />"; |
||
134 | } |
||
135 | |||
136 | return ret; |
||
137 | } |
||
138 | |||
139 | private static string FindFileReference(string refName, ProjectNode project) |
||
140 | { |
||
141 | foreach(ReferencePathNode refPath in project.ReferencePaths) |
||
142 | { |
||
143 | string fullPath = Helper.MakeFilePath(refPath.Path, refName, "dll"); |
||
144 | |||
145 | if(File.Exists(fullPath)) |
||
146 | { |
||
147 | return fullPath; |
||
148 | } |
||
149 | } |
||
150 | |||
151 | return null; |
||
152 | } |
||
153 | |||
154 | /// <summary> |
||
155 | /// Gets the XML doc file. |
||
156 | /// </summary> |
||
157 | /// <param name="project">The project.</param> |
||
158 | /// <param name="conf">The conf.</param> |
||
159 | /// <returns></returns> |
||
160 | public static string GenerateXmlDocFile(ProjectNode project, ConfigurationNode conf) |
||
161 | { |
||
162 | if( conf == null ) |
||
163 | { |
||
164 | throw new ArgumentNullException("conf"); |
||
165 | } |
||
166 | if( project == null ) |
||
167 | { |
||
168 | throw new ArgumentNullException("project"); |
||
169 | } |
||
170 | string docFile = (string)conf.Options["XmlDocFile"]; |
||
171 | if(docFile != null && docFile.Length == 0)//default to assembly name if not specified |
||
172 | { |
||
173 | return "False"; |
||
174 | } |
||
175 | return "True"; |
||
176 | } |
||
177 | |||
178 | private void WriteProject(SolutionNode solution, ProjectNode project) |
||
179 | { |
||
180 | string csComp = "Mcs"; |
||
181 | string netRuntime = "Mono"; |
||
182 | if(project.Runtime == ClrRuntime.Microsoft) |
||
183 | { |
||
184 | csComp = "Csc"; |
||
185 | netRuntime = "MsNet"; |
||
186 | } |
||
187 | |||
188 | string projFile = Helper.MakeFilePath(project.FullPath, project.Name, "mdp"); |
||
189 | StreamWriter ss = new StreamWriter(projFile); |
||
190 | |||
191 | m_Kernel.CurrentWorkingDirectory.Push(); |
||
192 | Helper.SetCurrentDir(Path.GetDirectoryName(projFile)); |
||
193 | |||
194 | using(ss) |
||
195 | { |
||
196 | ss.WriteLine( |
||
197 | "<Project name=\"{0}\" description=\"\" standardNamespace=\"{1}\" newfilesearch=\"None\" enableviewstate=\"True\" fileversion=\"2.0\" language=\"C#\" clr-version=\"Net_2_0\" ctype=\"DotNetProject\">", |
||
198 | project.Name, |
||
199 | project.RootNamespace |
||
200 | ); |
||
201 | |||
202 | int count = 0; |
||
203 | |||
204 | ss.WriteLine(" <Configurations active=\"{0}\">", solution.ActiveConfig); |
||
205 | |||
206 | foreach(ConfigurationNode conf in project.Configurations) |
||
207 | { |
||
208 | ss.WriteLine(" <Configuration name=\"{0}\" ctype=\"DotNetProjectConfiguration\">", conf.Name); |
||
209 | ss.Write(" <Output"); |
||
210 | ss.Write(" directory=\"{0}\"", Helper.EndPath(Helper.NormalizePath(".\\" + conf.Options["OutputPath"].ToString()))); |
||
211 | ss.Write(" assembly=\"{0}\"", project.AssemblyName); |
||
212 | ss.Write(" executeScript=\"{0}\"", conf.Options["RunScript"]); |
||
213 | //ss.Write(" executeBeforeBuild=\"{0}\"", conf.Options["PreBuildEvent"]); |
||
214 | //ss.Write(" executeAfterBuild=\"{0}\"", conf.Options["PostBuildEvent"]); |
||
215 | if (conf.Options["PreBuildEvent"] != null && conf.Options["PreBuildEvent"].ToString().Length != 0) |
||
216 | { |
||
217 | ss.Write(" executeBeforeBuild=\"{0}\"", Helper.NormalizePath(conf.Options["PreBuildEvent"].ToString())); |
||
218 | } |
||
219 | else |
||
220 | { |
||
221 | ss.Write(" executeBeforeBuild=\"{0}\"", conf.Options["PreBuildEvent"]); |
||
222 | } |
||
223 | if (conf.Options["PostBuildEvent"] != null && conf.Options["PostBuildEvent"].ToString().Length != 0) |
||
224 | { |
||
225 | ss.Write(" executeAfterBuild=\"{0}\"", Helper.NormalizePath(conf.Options["PostBuildEvent"].ToString())); |
||
226 | } |
||
227 | else |
||
228 | { |
||
229 | ss.Write(" executeAfterBuild=\"{0}\"", conf.Options["PostBuildEvent"]); |
||
230 | } |
||
231 | ss.Write(" executeBeforeBuildArguments=\"{0}\"", conf.Options["PreBuildEventArgs"]); |
||
232 | ss.Write(" executeAfterBuildArguments=\"{0}\"", conf.Options["PreBuildEventArgs"]); |
||
233 | ss.WriteLine(" />"); |
||
234 | |||
235 | ss.Write(" <Build"); |
||
236 | ss.Write(" debugmode=\"True\""); |
||
237 | if (project.Type == ProjectType.WinExe) |
||
238 | { |
||
239 | ss.Write(" target=\"{0}\"", ProjectType.Exe.ToString()); |
||
240 | } |
||
241 | else |
||
242 | { |
||
243 | ss.Write(" target=\"{0}\"", project.Type); |
||
244 | } |
||
245 | ss.WriteLine(" />"); |
||
246 | |||
247 | ss.Write(" <Execution"); |
||
248 | ss.Write(" runwithwarnings=\"{0}\"", !conf.Options.WarningsAsErrors); |
||
249 | ss.Write(" consolepause=\"True\""); |
||
250 | ss.Write(" runtime=\"{0}\"", netRuntime); |
||
251 | ss.Write(" clr-version=\"Net_2_0\""); |
||
252 | ss.WriteLine(" />"); |
||
253 | |||
254 | ss.Write(" <CodeGeneration"); |
||
255 | ss.Write(" compiler=\"{0}\"", csComp); |
||
256 | ss.Write(" warninglevel=\"{0}\"", conf.Options["WarningLevel"]); |
||
257 | ss.Write(" nowarn=\"{0}\"", conf.Options["SuppressWarnings"]); |
||
258 | ss.Write(" includedebuginformation=\"{0}\"", conf.Options["DebugInformation"]); |
||
259 | ss.Write(" optimize=\"{0}\"", conf.Options["OptimizeCode"]); |
||
260 | ss.Write(" unsafecodeallowed=\"{0}\"", conf.Options["AllowUnsafe"]); |
||
261 | ss.Write(" generateoverflowchecks=\"{0}\"", conf.Options["CheckUnderflowOverflow"]); |
||
262 | ss.Write(" mainclass=\"{0}\"", project.StartupObject); |
||
263 | ss.Write(" target=\"{0}\"", project.Type); |
||
264 | ss.Write(" definesymbols=\"{0}\"", conf.Options["CompilerDefines"]); |
||
265 | ss.Write(" generatexmldocumentation=\"{0}\"", GenerateXmlDocFile(project, conf)); |
||
266 | ss.Write(" win32Icon=\"{0}\"", project.AppIcon); |
||
267 | ss.Write(" ctype=\"CSharpCompilerParameters\""); |
||
268 | ss.WriteLine(" />"); |
||
269 | ss.WriteLine(" </Configuration>"); |
||
270 | |||
271 | count++; |
||
272 | } |
||
273 | ss.WriteLine(" </Configurations>"); |
||
274 | |||
275 | ss.Write(" <DeploymentInformation"); |
||
276 | ss.Write(" target=\"\""); |
||
277 | ss.Write(" script=\"\""); |
||
278 | ss.Write(" strategy=\"File\""); |
||
279 | ss.WriteLine(">"); |
||
280 | ss.WriteLine(" <excludeFiles />"); |
||
281 | ss.WriteLine(" </DeploymentInformation>"); |
||
282 | |||
283 | ss.WriteLine(" <Contents>"); |
||
284 | foreach(string file in project.Files) |
||
285 | { |
||
286 | string buildAction = "Compile"; |
||
287 | switch(project.Files.GetBuildAction(file)) |
||
288 | { |
||
289 | case BuildAction.None: |
||
290 | buildAction = "Nothing"; |
||
291 | break; |
||
292 | |||
293 | case BuildAction.Content: |
||
294 | buildAction = "Exclude"; |
||
295 | break; |
||
296 | |||
297 | case BuildAction.EmbeddedResource: |
||
298 | buildAction = "EmbedAsResource"; |
||
299 | break; |
||
300 | |||
301 | default: |
||
302 | buildAction = "Compile"; |
||
303 | break; |
||
304 | } |
||
305 | |||
306 | // Sort of a hack, we try and resolve the path and make it relative, if we can. |
||
307 | string filePath = PrependPath(file); |
||
308 | ss.WriteLine(" <File name=\"{0}\" subtype=\"Code\" buildaction=\"{1}\" dependson=\"\" data=\"\" />", filePath, buildAction); |
||
309 | } |
||
310 | ss.WriteLine(" </Contents>"); |
||
311 | |||
312 | ss.WriteLine(" <References>"); |
||
313 | foreach(ReferenceNode refr in project.References) |
||
314 | { |
||
315 | ss.WriteLine(" {0}", BuildReference(solution, refr)); |
||
316 | } |
||
317 | ss.WriteLine(" </References>"); |
||
318 | |||
319 | |||
320 | ss.WriteLine("</Project>"); |
||
321 | } |
||
322 | |||
323 | m_Kernel.CurrentWorkingDirectory.Pop(); |
||
324 | } |
||
325 | |||
326 | private void WriteCombine(SolutionNode solution) |
||
327 | { |
||
328 | m_Kernel.Log.Write("Creating MonoDevelop combine and project files"); |
||
329 | foreach(ProjectNode project in solution.Projects) |
||
330 | { |
||
331 | if(m_Kernel.AllowProject(project.FilterGroups)) |
||
332 | { |
||
333 | m_Kernel.Log.Write("...Creating project: {0}", project.Name); |
||
334 | WriteProject(solution, project); |
||
335 | } |
||
336 | } |
||
337 | |||
338 | m_Kernel.Log.Write(""); |
||
339 | string combFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "mds"); |
||
340 | StreamWriter ss = new StreamWriter(combFile); |
||
341 | |||
342 | m_Kernel.CurrentWorkingDirectory.Push(); |
||
343 | Helper.SetCurrentDir(Path.GetDirectoryName(combFile)); |
||
344 | |||
345 | int count = 0; |
||
346 | |||
347 | using(ss) |
||
348 | { |
||
349 | ss.WriteLine("<Combine name=\"{0}\" fileversion=\"2.0\" description=\"\">", solution.Name); |
||
350 | |||
351 | count = 0; |
||
352 | foreach(ConfigurationNode conf in solution.Configurations) |
||
353 | { |
||
354 | if(count == 0) |
||
355 | { |
||
356 | ss.WriteLine(" <Configurations active=\"{0}\">", conf.Name); |
||
357 | } |
||
358 | |||
359 | ss.WriteLine(" <Configuration name=\"{0}\" ctype=\"CombineConfiguration\">", conf.Name); |
||
360 | foreach(ProjectNode project in solution.Projects) |
||
361 | { |
||
362 | ss.WriteLine(" <Entry configuration=\"{1}\" build=\"True\" name=\"{0}\" />", project.Name, conf.Name); |
||
363 | } |
||
364 | ss.WriteLine(" </Configuration>"); |
||
365 | |||
366 | count++; |
||
367 | } |
||
368 | ss.WriteLine(" </Configurations>"); |
||
369 | |||
370 | count = 0; |
||
371 | |||
372 | foreach(ProjectNode project in solution.Projects) |
||
373 | { |
||
374 | if(count == 0) |
||
375 | ss.WriteLine(" <StartMode startupentry=\"{0}\" single=\"True\">", project.Name); |
||
376 | |||
377 | ss.WriteLine(" <Execute type=\"None\" entry=\"{0}\" />", project.Name); |
||
378 | count++; |
||
379 | } |
||
380 | ss.WriteLine(" </StartMode>"); |
||
381 | |||
382 | ss.WriteLine(" <Entries>"); |
||
383 | foreach(ProjectNode project in solution.Projects) |
||
384 | { |
||
385 | string path = Helper.MakePathRelativeTo(solution.FullPath, project.FullPath); |
||
386 | ss.WriteLine(" <Entry filename=\"{0}\" />", |
||
387 | Helper.MakeFilePath(path, project.Name, "mdp")); |
||
388 | } |
||
389 | ss.WriteLine(" </Entries>"); |
||
390 | |||
391 | ss.WriteLine("</Combine>"); |
||
392 | } |
||
393 | |||
394 | m_Kernel.CurrentWorkingDirectory.Pop(); |
||
395 | } |
||
396 | |||
397 | private void CleanProject(ProjectNode project) |
||
398 | { |
||
399 | m_Kernel.Log.Write("...Cleaning project: {0}", project.Name); |
||
400 | string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "mdp"); |
||
401 | Helper.DeleteIfExists(projectFile); |
||
402 | } |
||
403 | |||
404 | private void CleanSolution(SolutionNode solution) |
||
405 | { |
||
406 | m_Kernel.Log.Write("Cleaning MonoDevelop combine and project files for", solution.Name); |
||
407 | |||
408 | string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "mds"); |
||
409 | Helper.DeleteIfExists(slnFile); |
||
410 | |||
411 | foreach(ProjectNode project in solution.Projects) |
||
412 | { |
||
413 | CleanProject(project); |
||
414 | } |
||
415 | |||
416 | m_Kernel.Log.Write(""); |
||
417 | } |
||
418 | |||
419 | #endregion |
||
420 | |||
421 | #region ITarget Members |
||
422 | |||
423 | /// <summary> |
||
424 | /// Writes the specified kern. |
||
425 | /// </summary> |
||
426 | /// <param name="kern">The kern.</param> |
||
427 | public void Write(Kernel kern) |
||
428 | { |
||
429 | if( kern == null ) |
||
430 | { |
||
431 | throw new ArgumentNullException("kern"); |
||
432 | } |
||
433 | m_Kernel = kern; |
||
434 | foreach(SolutionNode solution in kern.Solutions) |
||
435 | { |
||
436 | WriteCombine(solution); |
||
437 | } |
||
438 | m_Kernel = null; |
||
439 | } |
||
440 | |||
441 | /// <summary> |
||
442 | /// Cleans the specified kern. |
||
443 | /// </summary> |
||
444 | /// <param name="kern">The kern.</param> |
||
445 | public virtual void Clean(Kernel kern) |
||
446 | { |
||
447 | if( kern == null ) |
||
448 | { |
||
449 | throw new ArgumentNullException("kern"); |
||
450 | } |
||
451 | m_Kernel = kern; |
||
452 | foreach(SolutionNode sol in kern.Solutions) |
||
453 | { |
||
454 | CleanSolution(sol); |
||
455 | } |
||
456 | m_Kernel = null; |
||
457 | } |
||
458 | |||
459 | /// <summary> |
||
460 | /// Gets the name. |
||
461 | /// </summary> |
||
462 | /// <value>The name.</value> |
||
463 | public string Name |
||
464 | { |
||
465 | get |
||
466 | { |
||
467 | return "sharpdev"; |
||
468 | } |
||
469 | } |
||
470 | |||
471 | #endregion |
||
472 | } |
||
473 | } |