opensim – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | eva | 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 | } |