opensim – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | eva | 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 | using System; |
||
27 | using System.IO; |
||
28 | using System.Reflection; |
||
29 | using System.Text.RegularExpressions; |
||
30 | |||
31 | using Prebuild.Core.Attributes; |
||
32 | using Prebuild.Core.Interfaces; |
||
33 | using Prebuild.Core.Nodes; |
||
34 | using Prebuild.Core.Utilities; |
||
35 | |||
36 | namespace Prebuild.Core.Targets |
||
37 | { |
||
38 | /// <summary> |
||
39 | /// |
||
40 | /// </summary> |
||
41 | [Target("monodev")] |
||
42 | public class MonoDevelopTarget : ITarget |
||
43 | { |
||
44 | #region Fields |
||
45 | |||
46 | private Kernel m_Kernel; |
||
47 | |||
48 | #endregion |
||
49 | |||
50 | #region Private Methods |
||
51 | |||
52 | private static string PrependPath(string path) |
||
53 | { |
||
54 | string tmpPath = Helper.NormalizePath(path, '/'); |
||
55 | Regex regex = new Regex(@"(\w):/(\w+)"); |
||
56 | Match match = regex.Match(tmpPath); |
||
57 | if(match.Success || tmpPath[0] == '.' || tmpPath[0] == '/') |
||
58 | { |
||
59 | tmpPath = Helper.NormalizePath(tmpPath); |
||
60 | } |
||
61 | else |
||
62 | { |
||
63 | tmpPath = Helper.NormalizePath("./" + tmpPath); |
||
64 | } |
||
65 | |||
66 | return tmpPath; |
||
67 | } |
||
68 | |||
69 | private static string BuildReference(SolutionNode solution, ReferenceNode refr) |
||
70 | { |
||
71 | string ret = "<ProjectReference type=\""; |
||
72 | if(solution.ProjectsTable.ContainsKey(refr.Name)) |
||
73 | { |
||
74 | ret += "Project\""; |
||
75 | ret += " localcopy=\"" + refr.LocalCopy.ToString() + "\" refto=\"" + refr.Name + "\" />"; |
||
76 | } |
||
77 | else |
||
78 | { |
||
79 | ProjectNode project = (ProjectNode)refr.Parent; |
||
80 | string fileRef = FindFileReference(refr.Name, project); |
||
81 | |||
82 | if(refr.Path != null || fileRef != null) |
||
83 | { |
||
84 | ret += "Assembly\" refto=\""; |
||
85 | |||
86 | string finalPath = (refr.Path != null) ? Helper.MakeFilePath(refr.Path, refr.Name, "dll") : fileRef; |
||
87 | |||
88 | ret += finalPath; |
||
89 | ret += "\" localcopy=\"" + refr.LocalCopy.ToString() + "\" />"; |
||
90 | return ret; |
||
91 | } |
||
92 | |||
93 | ret += "Gac\""; |
||
94 | ret += " localcopy=\"" + refr.LocalCopy.ToString() + "\""; |
||
95 | ret += " refto=\""; |
||
96 | try |
||
97 | { |
||
98 | /* |
||
99 | Day changed to 28 Mar 2007 |
||
100 | ... |
||
101 | 08:09 < cj> is there anything that replaces Assembly.LoadFromPartialName() ? |
||
102 | 08:09 < jonp> no |
||
103 | 08:10 < jonp> in their infinite wisdom [sic], microsoft decided that the |
||
104 | ability to load any assembly version by-name was an inherently |
||
105 | bad idea |
||
106 | 08:11 < cj> I'm thinking of a bunch of four-letter words right now... |
||
107 | 08:11 < cj> security through making it difficult for the developer!!! |
||
108 | 08:12 < jonp> just use the Obsolete API |
||
109 | 08:12 < jonp> it should still work |
||
110 | 08:12 < cj> alrighty. |
||
111 | 08:12 < jonp> you just get warnings when using it |
||
112 | */ |
||
113 | Assembly assem = Assembly.LoadWithPartialName(refr.Name); |
||
114 | ret += assem.FullName; |
||
115 | //ret += refr.Name; |
||
116 | } |
||
117 | catch (System.NullReferenceException e) |
||
118 | { |
||
119 | e.ToString(); |
||
120 | ret += refr.Name; |
||
121 | } |
||
122 | ret += "\" />"; |
||
123 | } |
||
124 | |||
125 | return ret; |
||
126 | } |
||
127 | |||
128 | private static string FindFileReference(string refName, ProjectNode project) |
||
129 | { |
||
130 | foreach(ReferencePathNode refPath in project.ReferencePaths) |
||
131 | { |
||
132 | string fullPath = Helper.MakeFilePath(refPath.Path, refName, "dll"); |
||
133 | |||
134 | if(File.Exists(fullPath)) |
||
135 | { |
||
136 | return fullPath; |
||
137 | } |
||
138 | } |
||
139 | |||
140 | return null; |
||
141 | } |
||
142 | |||
143 | /// <summary> |
||
144 | /// Gets the XML doc file. |
||
145 | /// </summary> |
||
146 | /// <param name="project">The project.</param> |
||
147 | /// <param name="conf">The conf.</param> |
||
148 | /// <returns></returns> |
||
149 | public static string GenerateXmlDocFile(ProjectNode project, ConfigurationNode conf) |
||
150 | { |
||
151 | if( conf == null ) |
||
152 | { |
||
153 | throw new ArgumentNullException("conf"); |
||
154 | } |
||
155 | if( project == null ) |
||
156 | { |
||
157 | throw new ArgumentNullException("project"); |
||
158 | } |
||
159 | string docFile = (string)conf.Options["XmlDocFile"]; |
||
160 | if(docFile != null && docFile.Length == 0)//default to assembly name if not specified |
||
161 | { |
||
162 | return "False"; |
||
163 | } |
||
164 | return "True"; |
||
165 | } |
||
166 | |||
167 | private void WriteProject(SolutionNode solution, ProjectNode project) |
||
168 | { |
||
169 | string csComp = "Mcs"; |
||
170 | string netRuntime = "Mono"; |
||
171 | if(project.Runtime == ClrRuntime.Microsoft) |
||
172 | { |
||
173 | csComp = "Csc"; |
||
174 | netRuntime = "MsNet"; |
||
175 | } |
||
176 | |||
177 | string projFile = Helper.MakeFilePath(project.FullPath, project.Name, "mdp"); |
||
178 | StreamWriter ss = new StreamWriter(projFile); |
||
179 | |||
180 | m_Kernel.CurrentWorkingDirectory.Push(); |
||
181 | Helper.SetCurrentDir(Path.GetDirectoryName(projFile)); |
||
182 | |||
183 | using(ss) |
||
184 | { |
||
185 | ss.WriteLine( |
||
186 | "<Project name=\"{0}\" description=\"\" standardNamespace=\"{1}\" newfilesearch=\"None\" enableviewstate=\"True\" fileversion=\"2.0\" language=\"C#\" clr-version=\"Net_2_0\" ctype=\"DotNetProject\">", |
||
187 | project.Name, |
||
188 | project.RootNamespace |
||
189 | ); |
||
190 | |||
191 | int count = 0; |
||
192 | |||
193 | ss.WriteLine(" <Configurations active=\"{0}\">", solution.ActiveConfig); |
||
194 | |||
195 | foreach(ConfigurationNode conf in project.Configurations) |
||
196 | { |
||
197 | ss.WriteLine(" <Configuration name=\"{0}\" ctype=\"DotNetProjectConfiguration\">", conf.Name); |
||
198 | ss.Write(" <Output"); |
||
199 | ss.Write(" directory=\"{0}\"", Helper.EndPath(Helper.NormalizePath(".\\" + conf.Options["OutputPath"].ToString()))); |
||
200 | ss.Write(" assembly=\"{0}\"", project.AssemblyName); |
||
201 | ss.Write(" executeScript=\"{0}\"", conf.Options["RunScript"]); |
||
202 | //ss.Write(" executeBeforeBuild=\"{0}\"", conf.Options["PreBuildEvent"]); |
||
203 | //ss.Write(" executeAfterBuild=\"{0}\"", conf.Options["PostBuildEvent"]); |
||
204 | if (conf.Options["PreBuildEvent"] != null && conf.Options["PreBuildEvent"].ToString().Length != 0) |
||
205 | { |
||
206 | ss.Write(" executeBeforeBuild=\"{0}\"", Helper.NormalizePath(conf.Options["PreBuildEvent"].ToString())); |
||
207 | } |
||
208 | else |
||
209 | { |
||
210 | ss.Write(" executeBeforeBuild=\"{0}\"", conf.Options["PreBuildEvent"]); |
||
211 | } |
||
212 | if (conf.Options["PostBuildEvent"] != null && conf.Options["PostBuildEvent"].ToString().Length != 0) |
||
213 | { |
||
214 | ss.Write(" executeAfterBuild=\"{0}\"", Helper.NormalizePath(conf.Options["PostBuildEvent"].ToString())); |
||
215 | } |
||
216 | else |
||
217 | { |
||
218 | ss.Write(" executeAfterBuild=\"{0}\"", conf.Options["PostBuildEvent"]); |
||
219 | } |
||
220 | ss.Write(" executeBeforeBuildArguments=\"{0}\"", conf.Options["PreBuildEventArgs"]); |
||
221 | ss.Write(" executeAfterBuildArguments=\"{0}\"", conf.Options["PreBuildEventArgs"]); |
||
222 | ss.WriteLine(" />"); |
||
223 | |||
224 | ss.Write(" <Build"); |
||
225 | ss.Write(" debugmode=\"True\""); |
||
226 | if (project.Type == ProjectType.WinExe) |
||
227 | { |
||
228 | ss.Write(" target=\"{0}\"", ProjectType.Exe.ToString()); |
||
229 | } |
||
230 | else |
||
231 | { |
||
232 | ss.Write(" target=\"{0}\"", project.Type); |
||
233 | } |
||
234 | ss.WriteLine(" />"); |
||
235 | |||
236 | ss.Write(" <Execution"); |
||
237 | ss.Write(" runwithwarnings=\"{0}\"", !conf.Options.WarningsAsErrors); |
||
238 | ss.Write(" consolepause=\"True\""); |
||
239 | ss.Write(" runtime=\"{0}\"", netRuntime); |
||
240 | ss.Write(" clr-version=\"Net_2_0\""); |
||
241 | ss.WriteLine(" />"); |
||
242 | |||
243 | ss.Write(" <CodeGeneration"); |
||
244 | ss.Write(" compiler=\"{0}\"", csComp); |
||
245 | ss.Write(" warninglevel=\"{0}\"", conf.Options["WarningLevel"]); |
||
246 | ss.Write(" nowarn=\"{0}\"", conf.Options["SuppressWarnings"]); |
||
247 | ss.Write(" includedebuginformation=\"{0}\"", conf.Options["DebugInformation"]); |
||
248 | ss.Write(" optimize=\"{0}\"", conf.Options["OptimizeCode"]); |
||
249 | ss.Write(" unsafecodeallowed=\"{0}\"", conf.Options["AllowUnsafe"]); |
||
250 | ss.Write(" generateoverflowchecks=\"{0}\"", conf.Options["CheckUnderflowOverflow"]); |
||
251 | ss.Write(" mainclass=\"{0}\"", project.StartupObject); |
||
252 | ss.Write(" target=\"{0}\"", project.Type); |
||
253 | ss.Write(" definesymbols=\"{0}\"", conf.Options["CompilerDefines"]); |
||
254 | ss.Write(" generatexmldocumentation=\"{0}\"", GenerateXmlDocFile(project, conf)); |
||
255 | ss.Write(" win32Icon=\"{0}\"", project.AppIcon); |
||
256 | ss.Write(" ctype=\"CSharpCompilerParameters\""); |
||
257 | ss.WriteLine(" />"); |
||
258 | ss.WriteLine(" </Configuration>"); |
||
259 | |||
260 | count++; |
||
261 | } |
||
262 | ss.WriteLine(" </Configurations>"); |
||
263 | |||
264 | ss.Write(" <DeploymentInformation"); |
||
265 | ss.Write(" target=\"\""); |
||
266 | ss.Write(" script=\"\""); |
||
267 | ss.Write(" strategy=\"File\""); |
||
268 | ss.WriteLine(">"); |
||
269 | ss.WriteLine(" <excludeFiles />"); |
||
270 | ss.WriteLine(" </DeploymentInformation>"); |
||
271 | |||
272 | ss.WriteLine(" <Contents>"); |
||
273 | foreach(string file in project.Files) |
||
274 | { |
||
275 | string buildAction; |
||
276 | string dependson = ""; |
||
277 | string resource_id = ""; |
||
278 | string copyToOutput = ""; |
||
279 | |||
280 | switch(project.Files.GetBuildAction(file)) |
||
281 | { |
||
282 | case BuildAction.None: |
||
283 | buildAction = "Nothing"; |
||
284 | break; |
||
285 | |||
286 | case BuildAction.Content: |
||
287 | buildAction = "Exclude"; |
||
288 | break; |
||
289 | |||
290 | case BuildAction.EmbeddedResource: |
||
291 | buildAction = "EmbedAsResource"; |
||
292 | break; |
||
293 | |||
294 | default: |
||
295 | buildAction = "Compile"; |
||
296 | break; |
||
297 | } |
||
298 | |||
299 | if (project.Files.GetCopyToOutput(file) != CopyToOutput.Never) |
||
300 | buildAction = "FileCopy"; |
||
301 | |||
302 | // Sort of a hack, we try and resolve the path and make it relative, if we can. |
||
303 | string extension = Path.GetExtension(file); |
||
304 | string designer_format = string.Format(".Designer{0}", extension); |
||
305 | |||
306 | if (file.EndsWith(designer_format)) |
||
307 | { |
||
308 | string basename = file.Substring(0, file.LastIndexOf(designer_format)); |
||
309 | string[] extensions = new string[] { ".cs", ".resx", ".settings" }; |
||
310 | |||
311 | foreach(string ext in extensions) |
||
312 | { |
||
313 | if (project.Files.Contains(basename + ext)) |
||
314 | { |
||
315 | dependson = string.Format(" dependson=\"{0}{1}\"", basename, ext); |
||
316 | break; |
||
317 | } |
||
318 | } |
||
319 | } |
||
320 | if (extension == ".resx") |
||
321 | { |
||
322 | buildAction = "EmbedAsResource"; |
||
323 | string basename = file.Substring(0, file.LastIndexOf(".resx")); |
||
324 | |||
325 | // Visual Studio type resx + form dependency |
||
326 | if (project.Files.Contains(basename + ".cs")) |
||
327 | { |
||
328 | dependson = string.Format(" dependson=\"{0}{1}\"", basename, ".cs"); |
||
329 | } |
||
330 | |||
331 | // We need to specify a resources file name to avoid MissingManifestResourceExceptions |
||
332 | // in libraries that are built. |
||
333 | resource_id = string.Format(" resource_id=\"{0}.{1}.resources\"", |
||
334 | project.AssemblyName, basename.Replace("/", ".")); |
||
335 | } |
||
336 | |||
337 | switch(project.Files.GetCopyToOutput(file)) |
||
338 | { |
||
339 | case CopyToOutput.Always: |
||
340 | copyToOutput = string.Format(" copyToOutputDirectory=\"Always\""); |
||
341 | break; |
||
342 | case CopyToOutput.PreserveNewest: |
||
343 | copyToOutput = string.Format(" copyToOutputDirectory=\"PreserveNewest\""); |
||
344 | break; |
||
345 | } |
||
346 | |||
347 | // Sort of a hack, we try and resolve the path and make it relative, if we can. |
||
348 | string filePath = PrependPath(file); |
||
349 | ss.WriteLine(" <File name=\"{0}\" subtype=\"Code\" buildaction=\"{1}\"{2}{3}{4} />", |
||
350 | filePath, buildAction, dependson, resource_id, copyToOutput); |
||
351 | } |
||
352 | ss.WriteLine(" </Contents>"); |
||
353 | |||
354 | ss.WriteLine(" <References>"); |
||
355 | foreach(ReferenceNode refr in project.References) |
||
356 | { |
||
357 | ss.WriteLine(" {0}", BuildReference(solution, refr)); |
||
358 | } |
||
359 | ss.WriteLine(" </References>"); |
||
360 | |||
361 | |||
362 | ss.WriteLine("</Project>"); |
||
363 | } |
||
364 | |||
365 | m_Kernel.CurrentWorkingDirectory.Pop(); |
||
366 | } |
||
367 | |||
368 | private void WriteCombine(SolutionNode solution) |
||
369 | { |
||
370 | m_Kernel.Log.Write("Creating MonoDevelop combine and project files"); |
||
371 | foreach(ProjectNode project in solution.Projects) |
||
372 | { |
||
373 | if(m_Kernel.AllowProject(project.FilterGroups)) |
||
374 | { |
||
375 | m_Kernel.Log.Write("...Creating project: {0}", project.Name); |
||
376 | WriteProject(solution, project); |
||
377 | } |
||
378 | } |
||
379 | |||
380 | m_Kernel.Log.Write(""); |
||
381 | string combFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "mds"); |
||
382 | StreamWriter ss = new StreamWriter(combFile); |
||
383 | |||
384 | m_Kernel.CurrentWorkingDirectory.Push(); |
||
385 | Helper.SetCurrentDir(Path.GetDirectoryName(combFile)); |
||
386 | |||
387 | int count = 0; |
||
388 | |||
389 | using(ss) |
||
390 | { |
||
391 | ss.WriteLine("<Combine name=\"{0}\" fileversion=\"2.0\" description=\"\">", solution.Name); |
||
392 | |||
393 | count = 0; |
||
394 | foreach(ConfigurationNode conf in solution.Configurations) |
||
395 | { |
||
396 | if(count == 0) |
||
397 | { |
||
398 | ss.WriteLine(" <Configurations active=\"{0}\">", conf.Name); |
||
399 | } |
||
400 | |||
401 | ss.WriteLine(" <Configuration name=\"{0}\" ctype=\"CombineConfiguration\">", conf.Name); |
||
402 | foreach(ProjectNode project in solution.Projects) |
||
403 | { |
||
404 | ss.WriteLine(" <Entry configuration=\"{1}\" build=\"True\" name=\"{0}\" />", project.Name, conf.Name); |
||
405 | } |
||
406 | ss.WriteLine(" </Configuration>"); |
||
407 | |||
408 | count++; |
||
409 | } |
||
410 | ss.WriteLine(" </Configurations>"); |
||
411 | |||
412 | count = 0; |
||
413 | |||
414 | foreach(ProjectNode project in solution.Projects) |
||
415 | { |
||
416 | if(count == 0) |
||
417 | ss.WriteLine(" <StartMode startupentry=\"{0}\" single=\"True\">", project.Name); |
||
418 | |||
419 | ss.WriteLine(" <Execute type=\"None\" entry=\"{0}\" />", project.Name); |
||
420 | count++; |
||
421 | } |
||
422 | ss.WriteLine(" </StartMode>"); |
||
423 | |||
424 | ss.WriteLine(" <Entries>"); |
||
425 | foreach(ProjectNode project in solution.Projects) |
||
426 | { |
||
427 | string path = Helper.MakePathRelativeTo(solution.FullPath, project.FullPath); |
||
428 | ss.WriteLine(" <Entry filename=\"{0}\" />", |
||
429 | Helper.MakeFilePath(path, project.Name, "mdp")); |
||
430 | } |
||
431 | ss.WriteLine(" </Entries>"); |
||
432 | |||
433 | ss.WriteLine("</Combine>"); |
||
434 | } |
||
435 | |||
436 | m_Kernel.CurrentWorkingDirectory.Pop(); |
||
437 | } |
||
438 | |||
439 | private void CleanProject(ProjectNode project) |
||
440 | { |
||
441 | m_Kernel.Log.Write("...Cleaning project: {0}", project.Name); |
||
442 | string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "mdp"); |
||
443 | Helper.DeleteIfExists(projectFile); |
||
444 | } |
||
445 | |||
446 | private void CleanSolution(SolutionNode solution) |
||
447 | { |
||
448 | m_Kernel.Log.Write("Cleaning MonoDevelop combine and project files for", solution.Name); |
||
449 | |||
450 | string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "mds"); |
||
451 | Helper.DeleteIfExists(slnFile); |
||
452 | |||
453 | foreach(ProjectNode project in solution.Projects) |
||
454 | { |
||
455 | CleanProject(project); |
||
456 | } |
||
457 | |||
458 | m_Kernel.Log.Write(""); |
||
459 | } |
||
460 | |||
461 | #endregion |
||
462 | |||
463 | #region ITarget Members |
||
464 | |||
465 | /// <summary> |
||
466 | /// Writes the specified kern. |
||
467 | /// </summary> |
||
468 | /// <param name="kern">The kern.</param> |
||
469 | public void Write(Kernel kern) |
||
470 | { |
||
471 | if( kern == null ) |
||
472 | { |
||
473 | throw new ArgumentNullException("kern"); |
||
474 | } |
||
475 | m_Kernel = kern; |
||
476 | foreach(SolutionNode solution in kern.Solutions) |
||
477 | { |
||
478 | WriteCombine(solution); |
||
479 | } |
||
480 | m_Kernel = null; |
||
481 | } |
||
482 | |||
483 | /// <summary> |
||
484 | /// Cleans the specified kern. |
||
485 | /// </summary> |
||
486 | /// <param name="kern">The kern.</param> |
||
487 | public virtual void Clean(Kernel kern) |
||
488 | { |
||
489 | if( kern == null ) |
||
490 | { |
||
491 | throw new ArgumentNullException("kern"); |
||
492 | } |
||
493 | m_Kernel = kern; |
||
494 | foreach(SolutionNode sol in kern.Solutions) |
||
495 | { |
||
496 | CleanSolution(sol); |
||
497 | } |
||
498 | m_Kernel = null; |
||
499 | } |
||
500 | |||
501 | /// <summary> |
||
502 | /// Gets the name. |
||
503 | /// </summary> |
||
504 | /// <value>The name.</value> |
||
505 | public string Name |
||
506 | { |
||
507 | get |
||
508 | { |
||
509 | return "sharpdev"; |
||
510 | } |
||
511 | } |
||
512 | |||
513 | #endregion |
||
514 | } |
||
515 | } |