aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Prebuild/src/Core/Targets/MonoDevelopTarget.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Prebuild/src/Core/Targets/MonoDevelopTarget.cs')
-rw-r--r--Prebuild/src/Core/Targets/MonoDevelopTarget.cs458
1 files changed, 458 insertions, 0 deletions
diff --git a/Prebuild/src/Core/Targets/MonoDevelopTarget.cs b/Prebuild/src/Core/Targets/MonoDevelopTarget.cs
new file mode 100644
index 0000000..8620e4b
--- /dev/null
+++ b/Prebuild/src/Core/Targets/MonoDevelopTarget.cs
@@ -0,0 +1,458 @@
1#region BSD License
2/*
3Copyright (c) 2004 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehead (dan05a@gmail.com)
4
5Redistribution and use in source and binary forms, with or without modification, are permitted
6provided 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
16THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
17BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
22IN 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: jendave $
30 * $Date: 2007-02-13 22:07:07 +0100 (ti, 13 feb 2007) $
31 * $Revision: 206 $
32 */
33#endregion
34
35using System;
36using System.Collections;
37using System.Collections.Specialized;
38using System.IO;
39using System.Reflection;
40using System.Text.RegularExpressions;
41
42using Prebuild.Core.Attributes;
43using Prebuild.Core.Interfaces;
44using Prebuild.Core.Nodes;
45using Prebuild.Core.Utilities;
46
47namespace 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 //Assembly assem = Assembly.Load(refr.Name);
110 //ret += assem.FullName;
111 ret += refr.Name;
112 }
113 catch (System.NullReferenceException e)
114 {
115 e.ToString();
116 ret += refr.Name;
117 }
118 ret += "\" />";
119 }
120
121 return ret;
122 }
123
124 private static string FindFileReference(string refName, ProjectNode project)
125 {
126 foreach(ReferencePathNode refPath in project.ReferencePaths)
127 {
128 string fullPath = Helper.MakeFilePath(refPath.Path, refName, "dll");
129
130 if(File.Exists(fullPath))
131 {
132 return fullPath;
133 }
134 }
135
136 return null;
137 }
138
139 /// <summary>
140 /// Gets the XML doc file.
141 /// </summary>
142 /// <param name="project">The project.</param>
143 /// <param name="conf">The conf.</param>
144 /// <returns></returns>
145 public static string GenerateXmlDocFile(ProjectNode project, ConfigurationNode conf)
146 {
147 if( conf == null )
148 {
149 throw new ArgumentNullException("conf");
150 }
151 if( project == null )
152 {
153 throw new ArgumentNullException("project");
154 }
155 string docFile = (string)conf.Options["XmlDocFile"];
156 if(docFile != null && docFile.Length == 0)//default to assembly name if not specified
157 {
158 return "False";
159 }
160 return "True";
161 }
162
163 private void WriteProject(SolutionNode solution, ProjectNode project)
164 {
165 string csComp = "Mcs";
166 string netRuntime = "Mono";
167 if(project.Runtime == ClrRuntime.Microsoft)
168 {
169 csComp = "Csc";
170 netRuntime = "MsNet";
171 }
172
173 string projFile = Helper.MakeFilePath(project.FullPath, project.Name, "mdp");
174 StreamWriter ss = new StreamWriter(projFile);
175
176 m_Kernel.CurrentWorkingDirectory.Push();
177 Helper.SetCurrentDir(Path.GetDirectoryName(projFile));
178
179 using(ss)
180 {
181 ss.WriteLine(
182 "<Project name=\"{0}\" description=\"\" standardNamespace=\"{1}\" newfilesearch=\"None\" enableviewstate=\"True\" fileversion=\"2.0\" language=\"C#\" clr-version=\"Net_2_0\" ctype=\"DotNetProject\">",
183 project.Name,
184 project.RootNamespace
185 );
186
187 int count = 0;
188
189 ss.WriteLine(" <Configurations active=\"{0}\">", solution.ActiveConfig);
190
191 foreach(ConfigurationNode conf in project.Configurations)
192 {
193 ss.WriteLine(" <Configuration name=\"{0}\" ctype=\"DotNetProjectConfiguration\">", conf.Name);
194 ss.Write(" <Output");
195 ss.Write(" directory=\"{0}\"", Helper.EndPath(Helper.NormalizePath(".\\" + conf.Options["OutputPath"].ToString())));
196 ss.Write(" assembly=\"{0}\"", project.AssemblyName);
197 ss.Write(" executeScript=\"{0}\"", conf.Options["RunScript"]);
198 //ss.Write(" executeBeforeBuild=\"{0}\"", conf.Options["PreBuildEvent"]);
199 //ss.Write(" executeAfterBuild=\"{0}\"", conf.Options["PostBuildEvent"]);
200 if (conf.Options["PreBuildEvent"] != null && conf.Options["PreBuildEvent"].ToString().Length != 0)
201 {
202 ss.Write(" executeBeforeBuild=\"{0}\"", Helper.NormalizePath(conf.Options["PreBuildEvent"].ToString()));
203 }
204 else
205 {
206 ss.Write(" executeBeforeBuild=\"{0}\"", conf.Options["PreBuildEvent"]);
207 }
208 if (conf.Options["PostBuildEvent"] != null && conf.Options["PostBuildEvent"].ToString().Length != 0)
209 {
210 ss.Write(" executeAfterBuild=\"{0}\"", Helper.NormalizePath(conf.Options["PostBuildEvent"].ToString()));
211 }
212 else
213 {
214 ss.Write(" executeAfterBuild=\"{0}\"", conf.Options["PostBuildEvent"]);
215 }
216 ss.Write(" executeBeforeBuildArguments=\"{0}\"", conf.Options["PreBuildEventArgs"]);
217 ss.Write(" executeAfterBuildArguments=\"{0}\"", conf.Options["PreBuildEventArgs"]);
218 ss.WriteLine(" />");
219
220 ss.Write(" <Build");
221 ss.Write(" debugmode=\"True\"");
222 if (project.Type == ProjectType.WinExe)
223 {
224 ss.Write(" target=\"{0}\"", ProjectType.Exe.ToString());
225 }
226 else
227 {
228 ss.Write(" target=\"{0}\"", project.Type);
229 }
230 ss.WriteLine(" />");
231
232 ss.Write(" <Execution");
233 ss.Write(" runwithwarnings=\"True\"");
234 ss.Write(" consolepause=\"True\"");
235 ss.Write(" runtime=\"{0}\"", netRuntime);
236 ss.Write(" clr-version=\"Net_2_0\"");
237 ss.WriteLine(" />");
238
239 ss.Write(" <CodeGeneration");
240 ss.Write(" compiler=\"{0}\"", csComp);
241 ss.Write(" warninglevel=\"{0}\"", conf.Options["WarningLevel"]);
242 ss.Write(" nowarn=\"{0}\"", conf.Options["SuppressWarnings"]);
243 ss.Write(" includedebuginformation=\"{0}\"", conf.Options["DebugInformation"]);
244 ss.Write(" optimize=\"{0}\"", conf.Options["OptimizeCode"]);
245 ss.Write(" unsafecodeallowed=\"{0}\"", conf.Options["AllowUnsafe"]);
246 ss.Write(" generateoverflowchecks=\"{0}\"", conf.Options["CheckUnderflowOverflow"]);
247 ss.Write(" mainclass=\"{0}\"", project.StartupObject);
248 ss.Write(" target=\"{0}\"", project.Type);
249 ss.Write(" definesymbols=\"{0}\"", conf.Options["CompilerDefines"]);
250 ss.Write(" generatexmldocumentation=\"{0}\"", GenerateXmlDocFile(project, conf));
251 ss.Write(" win32Icon=\"{0}\"", project.AppIcon);
252 ss.Write(" ctype=\"CSharpCompilerParameters\"");
253 ss.WriteLine(" />");
254 ss.WriteLine(" </Configuration>");
255
256 count++;
257 }
258 ss.WriteLine(" </Configurations>");
259
260 ss.Write(" <DeploymentInformation");
261 ss.Write(" target=\"\"");
262 ss.Write(" script=\"\"");
263 ss.Write(" strategy=\"File\"");
264 ss.WriteLine(">");
265 ss.WriteLine(" <excludeFiles />");
266 ss.WriteLine(" </DeploymentInformation>");
267
268 ss.WriteLine(" <Contents>");
269 foreach(string file in project.Files)
270 {
271 string buildAction = "Compile";
272 switch(project.Files.GetBuildAction(file))
273 {
274 case BuildAction.None:
275 buildAction = "Nothing";
276 break;
277
278 case BuildAction.Content:
279 buildAction = "Exclude";
280 break;
281
282 case BuildAction.EmbeddedResource:
283 buildAction = "EmbedAsResource";
284 break;
285
286 default:
287 buildAction = "Compile";
288 break;
289 }
290
291 // Sort of a hack, we try and resolve the path and make it relative, if we can.
292 string filePath = PrependPath(file);
293 ss.WriteLine(" <File name=\"{0}\" subtype=\"Code\" buildaction=\"{1}\" dependson=\"\" data=\"\" />", filePath, buildAction);
294 }
295 ss.WriteLine(" </Contents>");
296
297 ss.WriteLine(" <References>");
298 foreach(ReferenceNode refr in project.References)
299 {
300 ss.WriteLine(" {0}", BuildReference(solution, refr));
301 }
302 ss.WriteLine(" </References>");
303
304
305 ss.WriteLine("</Project>");
306 }
307
308 m_Kernel.CurrentWorkingDirectory.Pop();
309 }
310
311 private void WriteCombine(SolutionNode solution)
312 {
313 m_Kernel.Log.Write("Creating MonoDevelop combine and project files");
314 foreach(ProjectNode project in solution.Projects)
315 {
316 if(m_Kernel.AllowProject(project.FilterGroups))
317 {
318 m_Kernel.Log.Write("...Creating project: {0}", project.Name);
319 WriteProject(solution, project);
320 }
321 }
322
323 m_Kernel.Log.Write("");
324 string combFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "mds");
325 StreamWriter ss = new StreamWriter(combFile);
326
327 m_Kernel.CurrentWorkingDirectory.Push();
328 Helper.SetCurrentDir(Path.GetDirectoryName(combFile));
329
330 int count = 0;
331
332 using(ss)
333 {
334 ss.WriteLine("<Combine name=\"{0}\" fileversion=\"2.0\" description=\"\">", solution.Name);
335
336 count = 0;
337 foreach(ConfigurationNode conf in solution.Configurations)
338 {
339 if(count == 0)
340 {
341 ss.WriteLine(" <Configurations active=\"{0}\">", conf.Name);
342 }
343
344 ss.WriteLine(" <Configuration name=\"{0}\" ctype=\"CombineConfiguration\">", conf.Name);
345 foreach(ProjectNode project in solution.Projects)
346 {
347 ss.WriteLine(" <Entry configuration=\"{1}\" build=\"True\" name=\"{0}\" />", project.Name, conf.Name);
348 }
349 ss.WriteLine(" </Configuration>");
350
351 count++;
352 }
353 ss.WriteLine(" </Configurations>");
354
355 count = 0;
356
357 foreach(ProjectNode project in solution.Projects)
358 {
359 if(count == 0)
360 ss.WriteLine(" <StartMode startupentry=\"{0}\" single=\"True\">", project.Name);
361
362 ss.WriteLine(" <Execute type=\"None\" entry=\"{0}\" />", project.Name);
363 count++;
364 }
365 ss.WriteLine(" </StartMode>");
366
367 ss.WriteLine(" <Entries>");
368 foreach(ProjectNode project in solution.Projects)
369 {
370 string path = Helper.MakePathRelativeTo(solution.FullPath, project.FullPath);
371 ss.WriteLine(" <Entry filename=\"{0}\" />",
372 Helper.MakeFilePath(path, project.Name, "mdp"));
373 }
374 ss.WriteLine(" </Entries>");
375
376 ss.WriteLine("</Combine>");
377 }
378
379 m_Kernel.CurrentWorkingDirectory.Pop();
380 }
381
382 private void CleanProject(ProjectNode project)
383 {
384 m_Kernel.Log.Write("...Cleaning project: {0}", project.Name);
385 string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "mdp");
386 Helper.DeleteIfExists(projectFile);
387 }
388
389 private void CleanSolution(SolutionNode solution)
390 {
391 m_Kernel.Log.Write("Cleaning MonoDevelop combine and project files for", solution.Name);
392
393 string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "mds");
394 Helper.DeleteIfExists(slnFile);
395
396 foreach(ProjectNode project in solution.Projects)
397 {
398 CleanProject(project);
399 }
400
401 m_Kernel.Log.Write("");
402 }
403
404 #endregion
405
406 #region ITarget Members
407
408 /// <summary>
409 /// Writes the specified kern.
410 /// </summary>
411 /// <param name="kern">The kern.</param>
412 public void Write(Kernel kern)
413 {
414 if( kern == null )
415 {
416 throw new ArgumentNullException("kern");
417 }
418 m_Kernel = kern;
419 foreach(SolutionNode solution in kern.Solutions)
420 {
421 WriteCombine(solution);
422 }
423 m_Kernel = null;
424 }
425
426 /// <summary>
427 /// Cleans the specified kern.
428 /// </summary>
429 /// <param name="kern">The kern.</param>
430 public virtual void Clean(Kernel kern)
431 {
432 if( kern == null )
433 {
434 throw new ArgumentNullException("kern");
435 }
436 m_Kernel = kern;
437 foreach(SolutionNode sol in kern.Solutions)
438 {
439 CleanSolution(sol);
440 }
441 m_Kernel = null;
442 }
443
444 /// <summary>
445 /// Gets the name.
446 /// </summary>
447 /// <value>The name.</value>
448 public string Name
449 {
450 get
451 {
452 return "sharpdev";
453 }
454 }
455
456 #endregion
457 }
458}