diff options
author | Justin Clark-Casey (justincc) | 2010-09-11 01:13:08 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2010-09-11 01:13:08 +0100 |
commit | 7e65590a55ba575d0086bdfc25addaf1051d799b (patch) | |
tree | 1dc11683170d45d80d7aab6eefdfcc836d3e773b /Prebuild/src/Core/Targets/AutotoolsTarget.cs | |
parent | Make it clear that the "create region" command will reference ini files in th... (diff) | |
download | opensim-SC-7e65590a55ba575d0086bdfc25addaf1051d799b.zip opensim-SC-7e65590a55ba575d0086bdfc25addaf1051d799b.tar.gz opensim-SC-7e65590a55ba575d0086bdfc25addaf1051d799b.tar.bz2 opensim-SC-7e65590a55ba575d0086bdfc25addaf1051d799b.tar.xz |
Update Prebuild.exe with Prebuild r323 + an existing OpenSim specific nant hack to correctly clean up chosen OpenSim exes and dlls in bin/ on a "nant clean"
Source code is included for reference. This can go away again once Prebuild is updated with a more general mechanism for cleaning up files.
The Prebuild source code here can be built with nant, or regnerated for other tools using the prebuild at {root}/bin/Prebuild.exe
Diffstat (limited to 'Prebuild/src/Core/Targets/AutotoolsTarget.cs')
-rw-r--r-- | Prebuild/src/Core/Targets/AutotoolsTarget.cs | 1070 |
1 files changed, 1070 insertions, 0 deletions
diff --git a/Prebuild/src/Core/Targets/AutotoolsTarget.cs b/Prebuild/src/Core/Targets/AutotoolsTarget.cs new file mode 100644 index 0000000..e46b5a5 --- /dev/null +++ b/Prebuild/src/Core/Targets/AutotoolsTarget.cs | |||
@@ -0,0 +1,1070 @@ | |||
1 | #region BSD License | ||
2 | /* | ||
3 | |||
4 | Copyright (c) 2004 - 2008 | ||
5 | Matthew Holmes (matthew@wildfiregames.com), | ||
6 | Dan Moorehead (dan05a@gmail.com), | ||
7 | Dave Hudson (jendave@yahoo.com), | ||
8 | C.J. Adams-Collier (cjac@colliertech.org), | ||
9 | |||
10 | Redistribution and use in source and binary forms, with or without | ||
11 | modification, are permitted provided that the following conditions are | ||
12 | met: | ||
13 | |||
14 | * Redistributions of source code must retain the above copyright | ||
15 | notice, this list of conditions and the following disclaimer. | ||
16 | |||
17 | * Redistributions in binary form must reproduce the above copyright | ||
18 | notice, this list of conditions and the following disclaimer in the | ||
19 | documentation and/or other materials provided with the distribution. | ||
20 | |||
21 | * The name of the author may not be used to endorse or promote | ||
22 | products derived from this software without specific prior written | ||
23 | permission. | ||
24 | |||
25 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
26 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
27 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
28 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | ||
29 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
31 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
32 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
33 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
34 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
35 | POSSIBILITY OF SUCH DAMAGE. | ||
36 | |||
37 | */ | ||
38 | #endregion | ||
39 | |||
40 | #region MIT X11 license | ||
41 | |||
42 | /* | ||
43 | Portions of this file authored by Lluis Sanchez Gual | ||
44 | |||
45 | Copyright (C) 2006 Novell, Inc (http://www.novell.com) | ||
46 | |||
47 | Permission is hereby granted, free of charge, to any person obtaining | ||
48 | a copy of this software and associated documentation files (the | ||
49 | "Software"), to deal in the Software without restriction, including | ||
50 | without limitation the rights to use, copy, modify, merge, publish, | ||
51 | distribute, sublicense, and/or sell copies of the Software, and to | ||
52 | permit persons to whom the Software is furnished to do so, subject to | ||
53 | the following conditions: | ||
54 | |||
55 | The above copyright notice and this permission notice shall be | ||
56 | included in all copies or substantial portions of the Software. | ||
57 | |||
58 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
59 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
60 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
61 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
62 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
63 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
64 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
65 | */ | ||
66 | |||
67 | #endregion | ||
68 | using System; | ||
69 | using System.Collections.Generic; | ||
70 | using System.IO; | ||
71 | using System.Reflection; | ||
72 | using System.Text; | ||
73 | using System.Text.RegularExpressions; | ||
74 | using System.Xml; | ||
75 | using System.Xml.Xsl; | ||
76 | using System.Net; | ||
77 | using System.Diagnostics; | ||
78 | |||
79 | using Prebuild.Core.Attributes; | ||
80 | using Prebuild.Core.Interfaces; | ||
81 | using Prebuild.Core.Nodes; | ||
82 | using Prebuild.Core.Utilities; | ||
83 | |||
84 | namespace Prebuild.Core.Targets | ||
85 | { | ||
86 | public enum ClrVersion | ||
87 | { | ||
88 | Default, | ||
89 | Net_1_1, | ||
90 | Net_2_0 | ||
91 | } | ||
92 | |||
93 | public class SystemPackage | ||
94 | { | ||
95 | string name; | ||
96 | string version; | ||
97 | string description; | ||
98 | string[] assemblies; | ||
99 | bool isInternal; | ||
100 | ClrVersion targetVersion; | ||
101 | |||
102 | public void Initialize(string name, | ||
103 | string version, | ||
104 | string description, | ||
105 | string[] assemblies, | ||
106 | ClrVersion targetVersion, | ||
107 | bool isInternal) | ||
108 | { | ||
109 | this.isInternal = isInternal; | ||
110 | this.name = name; | ||
111 | this.version = version; | ||
112 | this.assemblies = assemblies; | ||
113 | this.description = description; | ||
114 | this.targetVersion = targetVersion; | ||
115 | } | ||
116 | |||
117 | public string Name | ||
118 | { | ||
119 | get { return name; } | ||
120 | } | ||
121 | |||
122 | public string Version | ||
123 | { | ||
124 | get { return version; } | ||
125 | } | ||
126 | |||
127 | public string Description | ||
128 | { | ||
129 | get { return description; } | ||
130 | } | ||
131 | |||
132 | public ClrVersion TargetVersion | ||
133 | { | ||
134 | get { return targetVersion; } | ||
135 | } | ||
136 | |||
137 | // The package is part of the mono SDK | ||
138 | public bool IsCorePackage | ||
139 | { | ||
140 | get { return name == "mono"; } | ||
141 | } | ||
142 | |||
143 | // The package has been registered by an add-in, and is not installed | ||
144 | // in the system. | ||
145 | public bool IsInternalPackage | ||
146 | { | ||
147 | get { return isInternal; } | ||
148 | } | ||
149 | |||
150 | public string[] Assemblies | ||
151 | { | ||
152 | get { return assemblies; } | ||
153 | } | ||
154 | |||
155 | } | ||
156 | |||
157 | |||
158 | /// <summary> | ||
159 | /// | ||
160 | /// </summary> | ||
161 | [Target("autotools")] | ||
162 | public class AutotoolsTarget : ITarget | ||
163 | { | ||
164 | #region Fields | ||
165 | |||
166 | Kernel m_Kernel; | ||
167 | XmlDocument autotoolsDoc; | ||
168 | XmlUrlResolver xr; | ||
169 | System.Security.Policy.Evidence e; | ||
170 | readonly Dictionary<string, SystemPackage> assemblyPathToPackage = new Dictionary<string, SystemPackage>(); | ||
171 | readonly Dictionary<string, string> assemblyFullNameToPath = new Dictionary<string, string>(); | ||
172 | readonly Dictionary<string, SystemPackage> packagesHash = new Dictionary<string, SystemPackage>(); | ||
173 | readonly List<SystemPackage> packages = new List<SystemPackage>(); | ||
174 | |||
175 | #endregion | ||
176 | |||
177 | #region Private Methods | ||
178 | |||
179 | private static void mkdirDashP(string dirName) | ||
180 | { | ||
181 | DirectoryInfo di = new DirectoryInfo(dirName); | ||
182 | if (di.Exists) | ||
183 | return; | ||
184 | |||
185 | string parentDirName = System.IO.Path.GetDirectoryName(dirName); | ||
186 | DirectoryInfo parentDi = new DirectoryInfo(parentDirName); | ||
187 | if (!parentDi.Exists) | ||
188 | mkdirDashP(parentDirName); | ||
189 | |||
190 | di.Create(); | ||
191 | } | ||
192 | |||
193 | private static void chkMkDir(string dirName) | ||
194 | { | ||
195 | System.IO.DirectoryInfo di = | ||
196 | new System.IO.DirectoryInfo(dirName); | ||
197 | |||
198 | if (!di.Exists) | ||
199 | di.Create(); | ||
200 | } | ||
201 | |||
202 | private void transformToFile(string filename, XsltArgumentList argList, string nodeName) | ||
203 | { | ||
204 | // Create an XslTransform for this file | ||
205 | XslTransform templateTransformer = | ||
206 | new XslTransform(); | ||
207 | |||
208 | // Load up the template | ||
209 | XmlNode templateNode = | ||
210 | autotoolsDoc.SelectSingleNode(nodeName + "/*"); | ||
211 | templateTransformer.Load(templateNode.CreateNavigator(), xr, e); | ||
212 | |||
213 | // Create a writer for the transformed template | ||
214 | XmlTextWriter templateWriter = | ||
215 | new XmlTextWriter(filename, null); | ||
216 | |||
217 | // Perform transformation, writing the file | ||
218 | templateTransformer.Transform | ||
219 | (m_Kernel.CurrentDoc, argList, templateWriter, xr); | ||
220 | } | ||
221 | |||
222 | static string NormalizeAsmName(string name) | ||
223 | { | ||
224 | int i = name.IndexOf(", PublicKeyToken=null"); | ||
225 | if (i != -1) | ||
226 | return name.Substring(0, i).Trim(); | ||
227 | return name; | ||
228 | } | ||
229 | |||
230 | private void AddAssembly(string assemblyfile, SystemPackage package) | ||
231 | { | ||
232 | if (!File.Exists(assemblyfile)) | ||
233 | return; | ||
234 | |||
235 | try | ||
236 | { | ||
237 | System.Reflection.AssemblyName an = System.Reflection.AssemblyName.GetAssemblyName(assemblyfile); | ||
238 | assemblyFullNameToPath[NormalizeAsmName(an.FullName)] = assemblyfile; | ||
239 | assemblyPathToPackage[assemblyfile] = package; | ||
240 | } | ||
241 | catch | ||
242 | { | ||
243 | } | ||
244 | } | ||
245 | |||
246 | private static List<string> GetAssembliesWithLibInfo(string line, string file) | ||
247 | { | ||
248 | List<string> references = new List<string>(); | ||
249 | List<string> libdirs = new List<string>(); | ||
250 | List<string> retval = new List<string>(); | ||
251 | foreach (string piece in line.Split(' ')) | ||
252 | { | ||
253 | if (piece.ToLower().Trim().StartsWith("/r:") || piece.ToLower().Trim().StartsWith("-r:")) | ||
254 | { | ||
255 | references.Add(ProcessPiece(piece.Substring(3).Trim(), file)); | ||
256 | } | ||
257 | else if (piece.ToLower().Trim().StartsWith("/lib:") || piece.ToLower().Trim().StartsWith("-lib:")) | ||
258 | { | ||
259 | libdirs.Add(ProcessPiece(piece.Substring(5).Trim(), file)); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | foreach (string refrnc in references) | ||
264 | { | ||
265 | foreach (string libdir in libdirs) | ||
266 | { | ||
267 | if (File.Exists(libdir + Path.DirectorySeparatorChar + refrnc)) | ||
268 | { | ||
269 | retval.Add(libdir + Path.DirectorySeparatorChar + refrnc); | ||
270 | } | ||
271 | } | ||
272 | } | ||
273 | |||
274 | return retval; | ||
275 | } | ||
276 | |||
277 | private static List<string> GetAssembliesWithoutLibInfo(string line, string file) | ||
278 | { | ||
279 | List<string> references = new List<string>(); | ||
280 | foreach (string reference in line.Split(' ')) | ||
281 | { | ||
282 | if (reference.ToLower().Trim().StartsWith("/r:") || reference.ToLower().Trim().StartsWith("-r:")) | ||
283 | { | ||
284 | string final_ref = reference.Substring(3).Trim(); | ||
285 | references.Add(ProcessPiece(final_ref, file)); | ||
286 | } | ||
287 | } | ||
288 | return references; | ||
289 | } | ||
290 | |||
291 | private static string ProcessPiece(string piece, string pcfile) | ||
292 | { | ||
293 | int start = piece.IndexOf("${"); | ||
294 | if (start == -1) | ||
295 | return piece; | ||
296 | |||
297 | int end = piece.IndexOf("}"); | ||
298 | if (end == -1) | ||
299 | return piece; | ||
300 | |||
301 | string variable = piece.Substring(start + 2, end - start - 2); | ||
302 | string interp = GetVariableFromPkgConfig(variable, Path.GetFileNameWithoutExtension(pcfile)); | ||
303 | return ProcessPiece(piece.Replace("${" + variable + "}", interp), pcfile); | ||
304 | } | ||
305 | |||
306 | private static string GetVariableFromPkgConfig(string var, string pcfile) | ||
307 | { | ||
308 | ProcessStartInfo psi = new ProcessStartInfo("pkg-config"); | ||
309 | psi.RedirectStandardOutput = true; | ||
310 | psi.UseShellExecute = false; | ||
311 | psi.Arguments = String.Format("--variable={0} {1}", var, pcfile); | ||
312 | Process p = new Process(); | ||
313 | p.StartInfo = psi; | ||
314 | p.Start(); | ||
315 | string ret = p.StandardOutput.ReadToEnd().Trim(); | ||
316 | p.WaitForExit(); | ||
317 | if (String.IsNullOrEmpty(ret)) | ||
318 | return String.Empty; | ||
319 | return ret; | ||
320 | } | ||
321 | |||
322 | private void ParsePCFile(string pcfile) | ||
323 | { | ||
324 | // Don't register the package twice | ||
325 | string pname = Path.GetFileNameWithoutExtension(pcfile); | ||
326 | if (packagesHash.ContainsKey(pname)) | ||
327 | return; | ||
328 | |||
329 | List<string> fullassemblies = null; | ||
330 | string version = ""; | ||
331 | string desc = ""; | ||
332 | |||
333 | SystemPackage package = new SystemPackage(); | ||
334 | |||
335 | using (StreamReader reader = new StreamReader(pcfile)) | ||
336 | { | ||
337 | string line; | ||
338 | while ((line = reader.ReadLine()) != null) | ||
339 | { | ||
340 | string lowerLine = line.ToLower(); | ||
341 | if (lowerLine.StartsWith("libs:") && lowerLine.IndexOf(".dll") != -1) | ||
342 | { | ||
343 | string choppedLine = line.Substring(5).Trim(); | ||
344 | if (choppedLine.IndexOf("-lib:") != -1 || choppedLine.IndexOf("/lib:") != -1) | ||
345 | { | ||
346 | fullassemblies = GetAssembliesWithLibInfo(choppedLine, pcfile); | ||
347 | } | ||
348 | else | ||
349 | { | ||
350 | fullassemblies = GetAssembliesWithoutLibInfo(choppedLine, pcfile); | ||
351 | } | ||
352 | } | ||
353 | else if (lowerLine.StartsWith("version:")) | ||
354 | { | ||
355 | // "version:".Length == 8 | ||
356 | version = line.Substring(8).Trim(); | ||
357 | } | ||
358 | else if (lowerLine.StartsWith("description:")) | ||
359 | { | ||
360 | // "description:".Length == 12 | ||
361 | desc = line.Substring(12).Trim(); | ||
362 | } | ||
363 | } | ||
364 | } | ||
365 | |||
366 | if (fullassemblies == null) | ||
367 | return; | ||
368 | |||
369 | foreach (string assembly in fullassemblies) | ||
370 | { | ||
371 | AddAssembly(assembly, package); | ||
372 | } | ||
373 | |||
374 | package.Initialize(pname, | ||
375 | version, | ||
376 | desc, | ||
377 | fullassemblies.ToArray(), | ||
378 | ClrVersion.Default, | ||
379 | false); | ||
380 | packages.Add(package); | ||
381 | packagesHash[pname] = package; | ||
382 | } | ||
383 | |||
384 | void RegisterSystemAssemblies(string prefix, string version, ClrVersion ver) | ||
385 | { | ||
386 | SystemPackage package = new SystemPackage(); | ||
387 | List<string> list = new List<string>(); | ||
388 | |||
389 | string dir = Path.Combine(prefix, version); | ||
390 | if (!Directory.Exists(dir)) | ||
391 | { | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | foreach (string assembly in Directory.GetFiles(dir, "*.dll")) | ||
396 | { | ||
397 | AddAssembly(assembly, package); | ||
398 | list.Add(assembly); | ||
399 | } | ||
400 | |||
401 | package.Initialize("mono", | ||
402 | version, | ||
403 | "The Mono runtime", | ||
404 | list.ToArray(), | ||
405 | ver, | ||
406 | false); | ||
407 | packages.Add(package); | ||
408 | } | ||
409 | |||
410 | void RunInitialization() | ||
411 | { | ||
412 | string versionDir; | ||
413 | |||
414 | if (Environment.Version.Major == 1) | ||
415 | { | ||
416 | versionDir = "1.0"; | ||
417 | } | ||
418 | else | ||
419 | { | ||
420 | versionDir = "2.0"; | ||
421 | } | ||
422 | |||
423 | //Pull up assemblies from the installed mono system. | ||
424 | string prefix = Path.GetDirectoryName(typeof(int).Assembly.Location); | ||
425 | |||
426 | if (prefix.IndexOf(Path.Combine("mono", versionDir)) == -1) | ||
427 | prefix = Path.Combine(prefix, "mono"); | ||
428 | else | ||
429 | prefix = Path.GetDirectoryName(prefix); | ||
430 | |||
431 | RegisterSystemAssemblies(prefix, "1.0", ClrVersion.Net_1_1); | ||
432 | RegisterSystemAssemblies(prefix, "2.0", ClrVersion.Net_2_0); | ||
433 | |||
434 | string search_dirs = Environment.GetEnvironmentVariable("PKG_CONFIG_PATH"); | ||
435 | string libpath = Environment.GetEnvironmentVariable("PKG_CONFIG_LIBPATH"); | ||
436 | |||
437 | if (String.IsNullOrEmpty(libpath)) | ||
438 | { | ||
439 | string path_dirs = Environment.GetEnvironmentVariable("PATH"); | ||
440 | foreach (string pathdir in path_dirs.Split(Path.PathSeparator)) | ||
441 | { | ||
442 | if (pathdir == null) | ||
443 | continue; | ||
444 | if (File.Exists(pathdir + Path.DirectorySeparatorChar + "pkg-config")) | ||
445 | { | ||
446 | libpath = Path.Combine(pathdir, ".."); | ||
447 | libpath = Path.Combine(libpath, "lib"); | ||
448 | libpath = Path.Combine(libpath, "pkgconfig"); | ||
449 | break; | ||
450 | } | ||
451 | } | ||
452 | } | ||
453 | search_dirs += Path.PathSeparator + libpath; | ||
454 | if (!string.IsNullOrEmpty(search_dirs)) | ||
455 | { | ||
456 | List<string> scanDirs = new List<string>(); | ||
457 | foreach (string potentialDir in search_dirs.Split(Path.PathSeparator)) | ||
458 | { | ||
459 | if (!scanDirs.Contains(potentialDir)) | ||
460 | scanDirs.Add(potentialDir); | ||
461 | } | ||
462 | foreach (string pcdir in scanDirs) | ||
463 | { | ||
464 | if (pcdir == null) | ||
465 | continue; | ||
466 | |||
467 | if (Directory.Exists(pcdir)) | ||
468 | { | ||
469 | foreach (string pcfile in Directory.GetFiles(pcdir, "*.pc")) | ||
470 | { | ||
471 | ParsePCFile(pcfile); | ||
472 | } | ||
473 | } | ||
474 | } | ||
475 | } | ||
476 | } | ||
477 | |||
478 | private void WriteCombine(SolutionNode solution) | ||
479 | { | ||
480 | #region "Create Solution directory if it doesn't exist" | ||
481 | string solutionDir = Path.Combine(solution.FullPath, | ||
482 | Path.Combine("autotools", | ||
483 | solution.Name)); | ||
484 | chkMkDir(solutionDir); | ||
485 | #endregion | ||
486 | |||
487 | #region "Write Solution-level files" | ||
488 | XsltArgumentList argList = new XsltArgumentList(); | ||
489 | argList.AddParam("solutionName", "", solution.Name); | ||
490 | // $solutionDir is $rootDir/$solutionName/ | ||
491 | transformToFile(Path.Combine(solutionDir, "configure.ac"), | ||
492 | argList, "/Autotools/SolutionConfigureAc"); | ||
493 | transformToFile(Path.Combine(solutionDir, "Makefile.am"), | ||
494 | argList, "/Autotools/SolutionMakefileAm"); | ||
495 | transformToFile(Path.Combine(solutionDir, "autogen.sh"), | ||
496 | argList, "/Autotools/SolutionAutogenSh"); | ||
497 | #endregion | ||
498 | |||
499 | foreach (ProjectNode project in solution.ProjectsTableOrder) | ||
500 | { | ||
501 | m_Kernel.Log.Write(String.Format("Writing project: {0}", | ||
502 | project.Name)); | ||
503 | WriteProject(solution, project); | ||
504 | } | ||
505 | } | ||
506 | |||
507 | private static string FindFileReference(string refName, | ||
508 | ProjectNode project) | ||
509 | { | ||
510 | foreach (ReferencePathNode refPath in project.ReferencePaths) | ||
511 | { | ||
512 | string fullPath = | ||
513 | Helper.MakeFilePath(refPath.Path, refName, "dll"); | ||
514 | |||
515 | if (File.Exists(fullPath)) { | ||
516 | return fullPath; | ||
517 | } | ||
518 | } | ||
519 | |||
520 | return null; | ||
521 | } | ||
522 | |||
523 | /// <summary> | ||
524 | /// Gets the XML doc file. | ||
525 | /// </summary> | ||
526 | /// <param name="project">The project.</param> | ||
527 | /// <param name="conf">The conf.</param> | ||
528 | /// <returns></returns> | ||
529 | public static string GetXmlDocFile(ProjectNode project, ConfigurationNode conf) | ||
530 | { | ||
531 | if (conf == null) | ||
532 | { | ||
533 | throw new ArgumentNullException("conf"); | ||
534 | } | ||
535 | if (project == null) | ||
536 | { | ||
537 | throw new ArgumentNullException("project"); | ||
538 | } | ||
539 | string docFile = (string)conf.Options["XmlDocFile"]; | ||
540 | // if(docFile != null && docFile.Length == 0)//default to assembly name if not specified | ||
541 | // { | ||
542 | // return Path.GetFileNameWithoutExtension(project.AssemblyName) + ".xml"; | ||
543 | // } | ||
544 | return docFile; | ||
545 | } | ||
546 | |||
547 | /// <summary> | ||
548 | /// Normalizes the path. | ||
549 | /// </summary> | ||
550 | /// <param name="path">The path.</param> | ||
551 | /// <returns></returns> | ||
552 | public static string NormalizePath(string path) | ||
553 | { | ||
554 | if (path == null) | ||
555 | { | ||
556 | return ""; | ||
557 | } | ||
558 | |||
559 | StringBuilder tmpPath; | ||
560 | |||
561 | if (Core.Parse.Preprocessor.GetOS() == "Win32") | ||
562 | { | ||
563 | tmpPath = new StringBuilder(path.Replace('\\', '/')); | ||
564 | tmpPath.Replace("/", @"\\"); | ||
565 | } | ||
566 | else | ||
567 | { | ||
568 | tmpPath = new StringBuilder(path.Replace('\\', '/')); | ||
569 | tmpPath = tmpPath.Replace('/', Path.DirectorySeparatorChar); | ||
570 | } | ||
571 | return tmpPath.ToString(); | ||
572 | } | ||
573 | |||
574 | private void WriteProject(SolutionNode solution, ProjectNode project) | ||
575 | { | ||
576 | string solutionDir = Path.Combine(solution.FullPath, Path.Combine("autotools", solution.Name)); | ||
577 | string projectDir = Path.Combine(solutionDir, project.Name); | ||
578 | string projectVersion = project.Version; | ||
579 | bool hasAssemblyConfig = false; | ||
580 | chkMkDir(projectDir); | ||
581 | |||
582 | List<string> | ||
583 | compiledFiles = new List<string>(), | ||
584 | contentFiles = new List<string>(), | ||
585 | embeddedFiles = new List<string>(), | ||
586 | |||
587 | binaryLibs = new List<string>(), | ||
588 | pkgLibs = new List<string>(), | ||
589 | systemLibs = new List<string>(), | ||
590 | runtimeLibs = new List<string>(), | ||
591 | |||
592 | extraDistFiles = new List<string>(), | ||
593 | localCopyTargets = new List<string>(); | ||
594 | |||
595 | // If there exists a .config file for this assembly, copy | ||
596 | // it to the project folder | ||
597 | |||
598 | // TODO: Support copying .config.osx files | ||
599 | // TODO: support processing the .config file for native library deps | ||
600 | string projectAssemblyName = project.Name; | ||
601 | if (project.AssemblyName != null) | ||
602 | projectAssemblyName = project.AssemblyName; | ||
603 | |||
604 | if (File.Exists(Path.Combine(project.FullPath, projectAssemblyName) + ".dll.config")) | ||
605 | { | ||
606 | hasAssemblyConfig = true; | ||
607 | System.IO.File.Copy(Path.Combine(project.FullPath, projectAssemblyName + ".dll.config"), Path.Combine(projectDir, projectAssemblyName + ".dll.config"), true); | ||
608 | extraDistFiles.Add(project.AssemblyName + ".dll.config"); | ||
609 | } | ||
610 | |||
611 | foreach (ConfigurationNode conf in project.Configurations) | ||
612 | { | ||
613 | if (conf.Options.KeyFile != string.Empty) | ||
614 | { | ||
615 | // Copy snk file into the project's directory | ||
616 | // Use the snk from the project directory directly | ||
617 | string source = Path.Combine(project.FullPath, conf.Options.KeyFile); | ||
618 | string keyFile = conf.Options.KeyFile; | ||
619 | Regex re = new Regex(".*/"); | ||
620 | keyFile = re.Replace(keyFile, ""); | ||
621 | |||
622 | string dest = Path.Combine(projectDir, keyFile); | ||
623 | // Tell the user if there's a problem copying the file | ||
624 | try | ||
625 | { | ||
626 | mkdirDashP(System.IO.Path.GetDirectoryName(dest)); | ||
627 | System.IO.File.Copy(source, dest, true); | ||
628 | } | ||
629 | catch (System.IO.IOException e) | ||
630 | { | ||
631 | Console.WriteLine(e.Message); | ||
632 | } | ||
633 | } | ||
634 | } | ||
635 | |||
636 | // Copy compiled, embedded and content files into the project's directory | ||
637 | foreach (string filename in project.Files) | ||
638 | { | ||
639 | string source = Path.Combine(project.FullPath, filename); | ||
640 | string dest = Path.Combine(projectDir, filename); | ||
641 | |||
642 | if (filename.Contains("AssemblyInfo.cs")) | ||
643 | { | ||
644 | // If we've got an AssemblyInfo.cs, pull the version number from it | ||
645 | string[] sources = { source }; | ||
646 | string[] args = { "" }; | ||
647 | Microsoft.CSharp.CSharpCodeProvider cscp = | ||
648 | new Microsoft.CSharp.CSharpCodeProvider(); | ||
649 | |||
650 | string tempAssemblyFile = Path.Combine(Path.GetTempPath(), project.Name + "-temp.dll"); | ||
651 | System.CodeDom.Compiler.CompilerParameters cparam = | ||
652 | new System.CodeDom.Compiler.CompilerParameters(args, tempAssemblyFile); | ||
653 | |||
654 | System.CodeDom.Compiler.CompilerResults cr = | ||
655 | cscp.CompileAssemblyFromFile(cparam, sources); | ||
656 | |||
657 | foreach (System.CodeDom.Compiler.CompilerError error in cr.Errors) | ||
658 | Console.WriteLine("Error! '{0}'", error.ErrorText); | ||
659 | |||
660 | try { | ||
661 | string projectFullName = cr.CompiledAssembly.FullName; | ||
662 | Regex verRegex = new Regex("Version=([\\d\\.]+)"); | ||
663 | Match verMatch = verRegex.Match(projectFullName); | ||
664 | if (verMatch.Success) | ||
665 | projectVersion = verMatch.Groups[1].Value; | ||
666 | }catch{ | ||
667 | Console.WriteLine("Couldn't compile AssemblyInfo.cs"); | ||
668 | } | ||
669 | |||
670 | // Clean up the temp file | ||
671 | try | ||
672 | { | ||
673 | if (File.Exists(tempAssemblyFile)) | ||
674 | File.Delete(tempAssemblyFile); | ||
675 | } | ||
676 | catch | ||
677 | { | ||
678 | Console.WriteLine("Error! '{0}'", e); | ||
679 | } | ||
680 | |||
681 | } | ||
682 | |||
683 | // Tell the user if there's a problem copying the file | ||
684 | try | ||
685 | { | ||
686 | mkdirDashP(System.IO.Path.GetDirectoryName(dest)); | ||
687 | System.IO.File.Copy(source, dest, true); | ||
688 | } | ||
689 | catch (System.IO.IOException e) | ||
690 | { | ||
691 | Console.WriteLine(e.Message); | ||
692 | } | ||
693 | |||
694 | switch (project.Files.GetBuildAction(filename)) | ||
695 | { | ||
696 | case BuildAction.Compile: | ||
697 | compiledFiles.Add(filename); | ||
698 | break; | ||
699 | case BuildAction.Content: | ||
700 | contentFiles.Add(filename); | ||
701 | extraDistFiles.Add(filename); | ||
702 | break; | ||
703 | case BuildAction.EmbeddedResource: | ||
704 | embeddedFiles.Add(filename); | ||
705 | break; | ||
706 | } | ||
707 | } | ||
708 | |||
709 | // Set up references | ||
710 | for (int refNum = 0; refNum < project.References.Count; refNum++) | ||
711 | { | ||
712 | ReferenceNode refr = project.References[refNum]; | ||
713 | Assembly refAssembly = Assembly.LoadWithPartialName(refr.Name); | ||
714 | |||
715 | /* Determine which pkg-config (.pc) file refers to | ||
716 | this assembly */ | ||
717 | |||
718 | SystemPackage package = null; | ||
719 | |||
720 | if (packagesHash.ContainsKey(refr.Name)) | ||
721 | { | ||
722 | package = packagesHash[refr.Name]; | ||
723 | |||
724 | } | ||
725 | else | ||
726 | { | ||
727 | string assemblyFullName = string.Empty; | ||
728 | if (refAssembly != null) | ||
729 | assemblyFullName = refAssembly.FullName; | ||
730 | |||
731 | string assemblyFileName = string.Empty; | ||
732 | if (assemblyFullName != string.Empty && | ||
733 | assemblyFullNameToPath.ContainsKey(assemblyFullName) | ||
734 | ) | ||
735 | assemblyFileName = | ||
736 | assemblyFullNameToPath[assemblyFullName]; | ||
737 | |||
738 | if (assemblyFileName != string.Empty && | ||
739 | assemblyPathToPackage.ContainsKey(assemblyFileName) | ||
740 | ) | ||
741 | package = assemblyPathToPackage[assemblyFileName]; | ||
742 | |||
743 | } | ||
744 | |||
745 | /* If we know the .pc file and it is not "mono" | ||
746 | (already in the path), add a -pkg: argument */ | ||
747 | |||
748 | if (package != null && | ||
749 | package.Name != "mono" && | ||
750 | !pkgLibs.Contains(package.Name) | ||
751 | ) | ||
752 | pkgLibs.Add(package.Name); | ||
753 | |||
754 | string fileRef = | ||
755 | FindFileReference(refr.Name, (ProjectNode)refr.Parent); | ||
756 | |||
757 | if (refr.LocalCopy || | ||
758 | solution.ProjectsTable.ContainsKey(refr.Name) || | ||
759 | fileRef != null || | ||
760 | refr.Path != null | ||
761 | ) | ||
762 | { | ||
763 | |||
764 | /* Attempt to copy the referenced lib to the | ||
765 | project's directory */ | ||
766 | |||
767 | string filename = refr.Name + ".dll"; | ||
768 | string source = filename; | ||
769 | if (refr.Path != null) | ||
770 | source = Path.Combine(refr.Path, source); | ||
771 | source = Path.Combine(project.FullPath, source); | ||
772 | string dest = Path.Combine(projectDir, filename); | ||
773 | |||
774 | /* Since we depend on this binary dll to build, we | ||
775 | * will add a compile- time dependency on the | ||
776 | * copied dll, and add the dll to the list of | ||
777 | * files distributed with this package | ||
778 | */ | ||
779 | |||
780 | binaryLibs.Add(refr.Name + ".dll"); | ||
781 | extraDistFiles.Add(refr.Name + ".dll"); | ||
782 | |||
783 | // TODO: Support copying .config.osx files | ||
784 | // TODO: Support for determining native dependencies | ||
785 | if (File.Exists(source + ".config")) | ||
786 | { | ||
787 | System.IO.File.Copy(source + ".config", Path.GetDirectoryName(dest), true); | ||
788 | extraDistFiles.Add(refr.Name + ".dll.config"); | ||
789 | } | ||
790 | |||
791 | try | ||
792 | { | ||
793 | System.IO.File.Copy(source, dest, true); | ||
794 | } | ||
795 | catch (System.IO.IOException) | ||
796 | { | ||
797 | if (solution.ProjectsTable.ContainsKey(refr.Name)){ | ||
798 | |||
799 | /* If an assembly is referenced, marked for | ||
800 | * local copy, in the list of projects for | ||
801 | * this solution, but does not exist, put a | ||
802 | * target into the Makefile.am to build the | ||
803 | * assembly and copy it to this project's | ||
804 | * directory | ||
805 | */ | ||
806 | |||
807 | ProjectNode sourcePrj = | ||
808 | ((solution.ProjectsTable[refr.Name])); | ||
809 | |||
810 | string target = | ||
811 | String.Format("{0}:\n" + | ||
812 | "\t$(MAKE) -C ../{1}\n" + | ||
813 | "\tln ../{2}/$@ $@\n", | ||
814 | filename, | ||
815 | sourcePrj.Name, | ||
816 | sourcePrj.Name ); | ||
817 | |||
818 | localCopyTargets.Add(target); | ||
819 | } | ||
820 | } | ||
821 | } | ||
822 | else if( !pkgLibs.Contains(refr.Name) ) | ||
823 | { | ||
824 | // Else, let's assume it's in the GAC or the lib path | ||
825 | string assemName = string.Empty; | ||
826 | int index = refr.Name.IndexOf(","); | ||
827 | |||
828 | if (index > 0) | ||
829 | assemName = refr.Name.Substring(0, index); | ||
830 | else | ||
831 | assemName = refr.Name; | ||
832 | |||
833 | m_Kernel.Log.Write(String.Format( | ||
834 | "Warning: Couldn't find an appropriate assembly " + | ||
835 | "for reference:\n'{0}'", refr.Name | ||
836 | )); | ||
837 | systemLibs.Add(assemName); | ||
838 | } | ||
839 | } | ||
840 | |||
841 | const string lineSep = " \\\n\t"; | ||
842 | string compiledFilesString = string.Empty; | ||
843 | if (compiledFiles.Count > 0) | ||
844 | compiledFilesString = | ||
845 | lineSep + string.Join(lineSep, compiledFiles.ToArray()); | ||
846 | |||
847 | string embeddedFilesString = ""; | ||
848 | if (embeddedFiles.Count > 0) | ||
849 | embeddedFilesString = | ||
850 | lineSep + string.Join(lineSep, embeddedFiles.ToArray()); | ||
851 | |||
852 | string contentFilesString = ""; | ||
853 | if (contentFiles.Count > 0) | ||
854 | contentFilesString = | ||
855 | lineSep + string.Join(lineSep, contentFiles.ToArray()); | ||
856 | |||
857 | string extraDistFilesString = ""; | ||
858 | if (extraDistFiles.Count > 0) | ||
859 | extraDistFilesString = | ||
860 | lineSep + string.Join(lineSep, extraDistFiles.ToArray()); | ||
861 | |||
862 | string pkgLibsString = ""; | ||
863 | if (pkgLibs.Count > 0) | ||
864 | pkgLibsString = | ||
865 | lineSep + string.Join(lineSep, pkgLibs.ToArray()); | ||
866 | |||
867 | string binaryLibsString = ""; | ||
868 | if (binaryLibs.Count > 0) | ||
869 | binaryLibsString = | ||
870 | lineSep + string.Join(lineSep, binaryLibs.ToArray()); | ||
871 | |||
872 | string systemLibsString = ""; | ||
873 | if (systemLibs.Count > 0) | ||
874 | systemLibsString = | ||
875 | lineSep + string.Join(lineSep, systemLibs.ToArray()); | ||
876 | |||
877 | string localCopyTargetsString = ""; | ||
878 | if (localCopyTargets.Count > 0) | ||
879 | localCopyTargetsString = | ||
880 | string.Join("\n", localCopyTargets.ToArray()); | ||
881 | |||
882 | string monoPath = ""; | ||
883 | foreach (string runtimeLib in runtimeLibs) | ||
884 | { | ||
885 | monoPath += ":`pkg-config --variable=libdir " + runtimeLib + "`"; | ||
886 | } | ||
887 | |||
888 | // Add the project name to the list of transformation | ||
889 | // parameters | ||
890 | XsltArgumentList argList = new XsltArgumentList(); | ||
891 | argList.AddParam("projectName", "", project.Name); | ||
892 | argList.AddParam("solutionName", "", solution.Name); | ||
893 | argList.AddParam("assemblyName", "", projectAssemblyName); | ||
894 | argList.AddParam("compiledFiles", "", compiledFilesString); | ||
895 | argList.AddParam("embeddedFiles", "", embeddedFilesString); | ||
896 | argList.AddParam("contentFiles", "", contentFilesString); | ||
897 | argList.AddParam("extraDistFiles", "", extraDistFilesString); | ||
898 | argList.AddParam("pkgLibs", "", pkgLibsString); | ||
899 | argList.AddParam("binaryLibs", "", binaryLibsString); | ||
900 | argList.AddParam("systemLibs", "", systemLibsString); | ||
901 | argList.AddParam("monoPath", "", monoPath); | ||
902 | argList.AddParam("localCopyTargets", "", localCopyTargetsString); | ||
903 | argList.AddParam("projectVersion", "", projectVersion); | ||
904 | argList.AddParam("hasAssemblyConfig", "", hasAssemblyConfig ? "true" : ""); | ||
905 | |||
906 | // Transform the templates | ||
907 | transformToFile(Path.Combine(projectDir, "configure.ac"), argList, "/Autotools/ProjectConfigureAc"); | ||
908 | transformToFile(Path.Combine(projectDir, "Makefile.am"), argList, "/Autotools/ProjectMakefileAm"); | ||
909 | transformToFile(Path.Combine(projectDir, "autogen.sh"), argList, "/Autotools/ProjectAutogenSh"); | ||
910 | |||
911 | if (project.Type == Core.Nodes.ProjectType.Library) | ||
912 | transformToFile(Path.Combine(projectDir, project.Name + ".pc.in"), argList, "/Autotools/ProjectPcIn"); | ||
913 | if (project.Type == Core.Nodes.ProjectType.Exe || project.Type == Core.Nodes.ProjectType.WinExe) | ||
914 | transformToFile(Path.Combine(projectDir, project.Name.ToLower() + ".in"), argList, "/Autotools/ProjectWrapperScriptIn"); | ||
915 | } | ||
916 | |||
917 | private void CleanProject(ProjectNode project) | ||
918 | { | ||
919 | m_Kernel.Log.Write("...Cleaning project: {0}", project.Name); | ||
920 | string projectFile = Helper.MakeFilePath(project.FullPath, "Include", "am"); | ||
921 | Helper.DeleteIfExists(projectFile); | ||
922 | } | ||
923 | |||
924 | private void CleanSolution(SolutionNode solution) | ||
925 | { | ||
926 | m_Kernel.Log.Write("Cleaning Autotools make files for", solution.Name); | ||
927 | |||
928 | string slnFile = Helper.MakeFilePath(solution.FullPath, "Makefile", "am"); | ||
929 | Helper.DeleteIfExists(slnFile); | ||
930 | |||
931 | slnFile = Helper.MakeFilePath(solution.FullPath, "Makefile", "in"); | ||
932 | Helper.DeleteIfExists(slnFile); | ||
933 | |||
934 | slnFile = Helper.MakeFilePath(solution.FullPath, "configure", "ac"); | ||
935 | Helper.DeleteIfExists(slnFile); | ||
936 | |||
937 | slnFile = Helper.MakeFilePath(solution.FullPath, "configure"); | ||
938 | Helper.DeleteIfExists(slnFile); | ||
939 | |||
940 | slnFile = Helper.MakeFilePath(solution.FullPath, "Makefile"); | ||
941 | Helper.DeleteIfExists(slnFile); | ||
942 | |||
943 | foreach (ProjectNode project in solution.Projects) | ||
944 | { | ||
945 | CleanProject(project); | ||
946 | } | ||
947 | |||
948 | m_Kernel.Log.Write(""); | ||
949 | } | ||
950 | |||
951 | #endregion | ||
952 | |||
953 | #region ITarget Members | ||
954 | |||
955 | /// <summary> | ||
956 | /// Writes the specified kern. | ||
957 | /// </summary> | ||
958 | /// <param name="kern">The kern.</param> | ||
959 | public void Write(Kernel kern) | ||
960 | { | ||
961 | if (kern == null) | ||
962 | { | ||
963 | throw new ArgumentNullException("kern"); | ||
964 | } | ||
965 | m_Kernel = kern; | ||
966 | m_Kernel.Log.Write("Parsing system pkg-config files"); | ||
967 | RunInitialization(); | ||
968 | |||
969 | const string streamName = "autotools.xml"; | ||
970 | string fqStreamName = String.Format("Prebuild.data.{0}", | ||
971 | streamName | ||
972 | ); | ||
973 | |||
974 | // Retrieve stream for the autotools template XML | ||
975 | Stream autotoolsStream = Assembly.GetExecutingAssembly() | ||
976 | .GetManifestResourceStream(fqStreamName); | ||
977 | |||
978 | if(autotoolsStream == null) { | ||
979 | |||
980 | /* | ||
981 | * try without the default namespace prepended, in | ||
982 | * case prebuild.exe assembly was compiled with | ||
983 | * something other than Visual Studio .NET | ||
984 | */ | ||
985 | |||
986 | autotoolsStream = Assembly.GetExecutingAssembly() | ||
987 | .GetManifestResourceStream(streamName); | ||
988 | if(autotoolsStream == null){ | ||
989 | string errStr = | ||
990 | String.Format("Could not find embedded resource file:\n" + | ||
991 | "'{0}' or '{1}'", | ||
992 | streamName, fqStreamName | ||
993 | ); | ||
994 | |||
995 | m_Kernel.Log.Write(errStr); | ||
996 | |||
997 | throw new System.Reflection.TargetException(errStr); | ||
998 | } | ||
999 | } | ||
1000 | |||
1001 | // Create an XML URL Resolver with default credentials | ||
1002 | xr = new System.Xml.XmlUrlResolver(); | ||
1003 | xr.Credentials = CredentialCache.DefaultCredentials; | ||
1004 | |||
1005 | // Create a default evidence - no need to limit access | ||
1006 | e = new System.Security.Policy.Evidence(); | ||
1007 | |||
1008 | // Load the autotools XML | ||
1009 | autotoolsDoc = new XmlDocument(); | ||
1010 | autotoolsDoc.Load(autotoolsStream); | ||
1011 | |||
1012 | /* rootDir is the filesystem location where the Autotools | ||
1013 | * build tree will be created - for now we'll make it | ||
1014 | * $PWD/autotools | ||
1015 | */ | ||
1016 | |||
1017 | string pwd = Directory.GetCurrentDirectory(); | ||
1018 | //string pwd = System.Environment.GetEnvironmentVariable("PWD"); | ||
1019 | //if (pwd.Length != 0) | ||
1020 | //{ | ||
1021 | string rootDir = Path.Combine(pwd, "autotools"); | ||
1022 | //} | ||
1023 | //else | ||
1024 | //{ | ||
1025 | // pwd = Assembly.GetExecutingAssembly() | ||
1026 | //} | ||
1027 | chkMkDir(rootDir); | ||
1028 | |||
1029 | foreach (SolutionNode solution in kern.Solutions) | ||
1030 | { | ||
1031 | m_Kernel.Log.Write(String.Format("Writing solution: {0}", | ||
1032 | solution.Name)); | ||
1033 | WriteCombine(solution); | ||
1034 | } | ||
1035 | m_Kernel = null; | ||
1036 | } | ||
1037 | |||
1038 | /// <summary> | ||
1039 | /// Cleans the specified kern. | ||
1040 | /// </summary> | ||
1041 | /// <param name="kern">The kern.</param> | ||
1042 | public virtual void Clean(Kernel kern) | ||
1043 | { | ||
1044 | if (kern == null) | ||
1045 | { | ||
1046 | throw new ArgumentNullException("kern"); | ||
1047 | } | ||
1048 | m_Kernel = kern; | ||
1049 | foreach (SolutionNode sol in kern.Solutions) | ||
1050 | { | ||
1051 | CleanSolution(sol); | ||
1052 | } | ||
1053 | m_Kernel = null; | ||
1054 | } | ||
1055 | |||
1056 | /// <summary> | ||
1057 | /// Gets the name. | ||
1058 | /// </summary> | ||
1059 | /// <value>The name.</value> | ||
1060 | public string Name | ||
1061 | { | ||
1062 | get | ||
1063 | { | ||
1064 | return "autotools"; | ||
1065 | } | ||
1066 | } | ||
1067 | |||
1068 | #endregion | ||
1069 | } | ||
1070 | } | ||