corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
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 }