clockwerk-opensim – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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 }