aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Prebuild/src/Core/Targets/AutotoolsTarget.cs
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2010-09-11 01:13:08 +0100
committerJustin Clark-Casey (justincc)2010-09-11 01:13:08 +0100
commit7e65590a55ba575d0086bdfc25addaf1051d799b (patch)
tree1dc11683170d45d80d7aab6eefdfcc836d3e773b /Prebuild/src/Core/Targets/AutotoolsTarget.cs
parentMake it clear that the "create region" command will reference ini files in th... (diff)
downloadopensim-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.cs1070
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
4Copyright (c) 2004 - 2008
5Matthew Holmes (matthew@wildfiregames.com),
6Dan Moorehead (dan05a@gmail.com),
7Dave Hudson (jendave@yahoo.com),
8C.J. Adams-Collier (cjac@colliertech.org),
9
10Redistribution and use in source and binary forms, with or without
11modification, are permitted provided that the following conditions are
12met:
13
14* Redistributions of source code must retain the above copyright
15notice, this list of conditions and the following disclaimer.
16
17* Redistributions in binary form must reproduce the above copyright
18notice, this list of conditions and the following disclaimer in the
19documentation and/or other materials provided with the distribution.
20
21* The name of the author may not be used to endorse or promote
22products derived from this software without specific prior written
23permission.
24
25THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
29INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
34IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35POSSIBILITY 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
68using System;
69using System.Collections.Generic;
70using System.IO;
71using System.Reflection;
72using System.Text;
73using System.Text.RegularExpressions;
74using System.Xml;
75using System.Xml.Xsl;
76using System.Net;
77using System.Diagnostics;
78
79using Prebuild.Core.Attributes;
80using Prebuild.Core.Interfaces;
81using Prebuild.Core.Nodes;
82using Prebuild.Core.Utilities;
83
84namespace 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}