+++ /dev/null
-//
-// Main.cs: Main program file of command line utility.
-//
-// Author:
-// Marek Sieradzki (marek.sieradzki@gmail.com)
-// Miguel de Icaza (miguel@ximian.com)
-// Marek Safar (marek.safar@seznam.cz)
-//
-// (C) 2005 Marek Sieradzki
-// Copyright 2009 Novell, Inc (http://www.novell.com)
-// Copyright 2011 Xamarin Inc (http://www.xamarin.com).
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-using Microsoft.Build.Utilities;
-using Microsoft.Build.Exceptions;
-using Microsoft.Build.Construction;
-using System.Xml;
-using System.Xml.Schema;
-using System.Linq;
-using System.Collections.Generic;
-
-
-using System;
-using System.Collections;
-using System.IO;
-using System.Reflection;
-using System.Text;
-using Microsoft.Build.Evaluation;
-using Microsoft.Build.Execution;
-using Microsoft.Build.Framework;
-using Microsoft.Build.Logging;
-using Mono.XBuild.Framework;
-
-class MonoTODOAttribute : Attribute
-{
-}
-
-namespace Mono.XBuild.CommandLine {
- public class MainClass {
-
- Parameters parameters;
- string[] args;
- string defaultSchema;
-
- ProjectCollection project_collection;
- ProjectRootElement project;
- ConsoleReportPrinter printer;
-
-
- public static void Main (string[] args)
- {
- MainClass mc = new MainClass ();
- mc.args = args;
- mc.Execute ();
- }
-
- public MainClass ()
- {
- string binPath = ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20);
- defaultSchema = Path.Combine (binPath, "Microsoft.Build.xsd");
- parameters = new Parameters ();
- }
-
- public void Execute ()
- {
- bool result = false;
- bool show_stacktrace = false;
-
- try {
- parameters.ParseArguments (args);
- show_stacktrace = (parameters.LoggerVerbosity == LoggerVerbosity.Detailed ||
- parameters.LoggerVerbosity == LoggerVerbosity.Diagnostic);
-
- if (!parameters.NoLogo)
- ErrorUtilities.ShowVersion (false);
-
- project_collection = new ProjectCollection ();
- if (!String.IsNullOrEmpty (parameters.ToolsVersion)) {
- if (project_collection.GetToolset (parameters.ToolsVersion) == null)
- ErrorUtilities.ReportError (0, new InvalidToolsetDefinitionException ("Toolset " + parameters.ToolsVersion + " was not found").Message);
-
- project_collection.DefaultToolsVersion = parameters.ToolsVersion;
- }
-
- foreach (var p in parameters.Properties)
- project_collection.GlobalProperties.Add (p.Key, p.Value);
-
- if (!parameters.NoConsoleLogger) {
- printer = new ConsoleReportPrinter ();
- ConsoleLogger cl = new ConsoleLogger (parameters.LoggerVerbosity,
- printer.Print, printer.SetForeground, printer.ResetColor);
-
- cl.Parameters = parameters.ConsoleLoggerParameters;
- cl.Verbosity = parameters.LoggerVerbosity;
- project_collection.RegisterLogger (cl);
- }
-
- if (parameters.FileLoggerParameters != null) {
- for (int i = 0; i < parameters.FileLoggerParameters.Length; i ++) {
- string fl_params = parameters.FileLoggerParameters [i];
- if (fl_params == null)
- continue;
-
- var fl = new FileLogger ();
- if (fl_params.Length == 0 && i > 0)
- fl.Parameters = String.Format ("LogFile=msbuild{0}.log", i);
- else
- fl.Parameters = fl_params;
- project_collection.RegisterLogger (fl);
- }
- }
-
- foreach (LoggerInfo li in parameters.Loggers) {
- Assembly assembly;
- if (li.InfoType == LoadInfoType.AssemblyFilename)
- assembly = Assembly.LoadFrom (li.Filename);
- else
- assembly = Assembly.Load (li.AssemblyName);
- ILogger logger = (ILogger)Activator.CreateInstance (assembly.GetType (li.ClassName));
- logger.Parameters = li.Parameters;
- project_collection.RegisterLogger (logger);
- }
-
- string projectFile = parameters.ProjectFile;
- if (!File.Exists (projectFile)) {
- ErrorUtilities.ReportError (0, String.Format ("Project file '{0}' not found.", projectFile));
- return;
- }
-
- XmlReaderSettings settings = new XmlReaderSettings ();
- if (parameters.Validate) {
- settings.ValidationType = ValidationType.Schema;
- if (parameters.ValidationSchema == null)
- using (var xsdxml = XmlReader.Create (defaultSchema))
- settings.Schemas.Add (XmlSchema.Read (xsdxml, null));
- else
- using (var xsdxml = XmlReader.Create (parameters.ValidationSchema))
- settings.Schemas.Add (XmlSchema.Read (xsdxml, null));
- }
-
- var projectInstances = new List<ProjectInstance> ();
- if (string.Equals (Path.GetExtension (projectFile), ".sln", StringComparison.OrdinalIgnoreCase)) {
- var parser = new SolutionParser ();
- var root = ProjectRootElement.Create (project_collection);
- root.FullPath = projectFile;
- parser.ParseSolution (projectFile, project_collection, root, LogWarning);
- projectInstances.Add (new Project (root, parameters.Properties, parameters.ToolsVersion, project_collection).CreateProjectInstance ());
- } else {
- project = ProjectRootElement.Create (XmlReader.Create (projectFile, settings), project_collection);
- project.FullPath = projectFile;
- var pi = new ProjectInstance (project, parameters.Properties, parameters.ToolsVersion, project_collection);
- projectInstances.Add (pi);
- }
- foreach (var projectInstance in projectInstances) {
- var targets = parameters.Targets.Length > 0 ? parameters.Targets : projectInstance.DefaultTargets.ToArray ();
- result = projectInstance.Build (targets, parameters.Loggers.Count > 0 ? parameters.Loggers : project_collection.Loggers);
- if (!result)
- break;
- }
- }
-
- catch (InvalidProjectFileException ipfe) {
- ErrorUtilities.ReportError (0, show_stacktrace ? ipfe.ToString () : ipfe.Message);
- }
-
- catch (InternalLoggerException ile) {
- ErrorUtilities.ReportError (0, show_stacktrace ? ile.ToString () : ile.Message);
- }
-
- catch (CommandLineException cle) {
- ErrorUtilities.ReportError(cle.ErrorCode, show_stacktrace ? cle.ToString() : cle.Message);
- }
- finally {
- //if (project_collection != null)
- // project_collection.UnregisterAllLoggers ();
-
- Environment.Exit (result ? 0 : 1);
- }
- }
-
- void LogWarning (int errorNumber, string message)
- {
- Console.Error.WriteLine ("Warning {0}: {1}", errorNumber, message);
- }
- }
-
- // code from mcs/report.cs
- class ConsoleReportPrinter
- {
- string prefix, postfix;
- bool color_supported;
- TextWriter writer;
- string [] colorPrefixes;
-
- public ConsoleReportPrinter ()
- : this (Console.Out)
- {
- }
-
- public ConsoleReportPrinter (TextWriter writer)
- {
- this.writer = writer;
-
- string term = Environment.GetEnvironmentVariable ("TERM");
- bool xterm_colors = false;
-
- color_supported = false;
- switch (term){
- case "xterm":
- case "rxvt":
- case "rxvt-unicode":
- if (Environment.GetEnvironmentVariable ("COLORTERM") != null){
- xterm_colors = true;
- }
- break;
-
- case "xterm-color":
- case "xterm-256color":
- xterm_colors = true;
- break;
- }
- if (!xterm_colors)
- return;
-
- if (!(UnixUtils.isatty (1) && UnixUtils.isatty (2)))
- return;
-
- color_supported = true;
- PopulateColorPrefixes ();
- postfix = "\x001b[0m";
- }
-
- void PopulateColorPrefixes ()
- {
- colorPrefixes = new string [16];
-
- colorPrefixes [(int)ConsoleColor.Black] = GetForeground ("black");
- colorPrefixes [(int)ConsoleColor.DarkBlue] = GetForeground ("blue");
- colorPrefixes [(int)ConsoleColor.DarkGreen] = GetForeground ("green");
- colorPrefixes [(int)ConsoleColor.DarkCyan] = GetForeground ("cyan");
- colorPrefixes [(int)ConsoleColor.DarkRed] = GetForeground ("red");
- colorPrefixes [(int)ConsoleColor.DarkMagenta] = GetForeground ("magenta");
- colorPrefixes [(int)ConsoleColor.DarkYellow] = GetForeground ("yellow");
- colorPrefixes [(int)ConsoleColor.DarkGray] = GetForeground ("grey");
-
- colorPrefixes [(int)ConsoleColor.Gray] = GetForeground ("brightgrey");
- colorPrefixes [(int)ConsoleColor.Blue] = GetForeground ("brightblue");
- colorPrefixes [(int)ConsoleColor.Green] = GetForeground ("brightgreen");
- colorPrefixes [(int)ConsoleColor.Cyan] = GetForeground ("brightcyan");
- colorPrefixes [(int)ConsoleColor.Red] = GetForeground ("brightred");
- colorPrefixes [(int)ConsoleColor.Magenta] = GetForeground ("brightmagenta");
- colorPrefixes [(int)ConsoleColor.Yellow] = GetForeground ("brightyellow");
-
- colorPrefixes [(int)ConsoleColor.White] = GetForeground ("brightwhite");
- }
-
- public void SetForeground (ConsoleColor color)
- {
- if (color_supported)
- prefix = colorPrefixes [(int)color];
- }
-
- public void ResetColor ()
- {
- prefix = "\x001b[0m";
- }
-
- static int NameToCode (string s)
- {
- switch (s) {
- case "black":
- return 0;
- case "red":
- return 1;
- case "green":
- return 2;
- case "yellow":
- return 3;
- case "blue":
- return 4;
- case "magenta":
- return 5;
- case "cyan":
- return 6;
- case "grey":
- case "white":
- return 7;
- }
- return 7;
- }
-
- //
- // maps a color name to its xterm color code
- //
- static string GetForeground (string s)
- {
- string highcode;
-
- if (s.StartsWith ("bright")) {
- highcode = "1;";
- s = s.Substring (6);
- } else
- highcode = "";
-
- return "\x001b[" + highcode + (30 + NameToCode (s)).ToString () + "m";
- }
-
- static string GetBackground (string s)
- {
- return "\x001b[" + (40 + NameToCode (s)).ToString () + "m";
- }
-
- string FormatText (string txt)
- {
- if (prefix != null && color_supported)
- return prefix + txt + postfix;
-
- return txt;
- }
-
- public void Print (string message)
- {
- writer.WriteLine (FormatText (message));
- }
-
- }
-
- class UnixUtils {
- [System.Runtime.InteropServices.DllImport ("libc", EntryPoint="isatty")]
- extern static int _isatty (int fd);
-
- public static bool isatty (int fd)
- {
- try {
- return _isatty (fd) == 1;
- } catch {
- return false;
- }
- }
- }
-
-}
-
+++ /dev/null
-//
-// Parameters.cs: Class that contains information about command line parameters
-//
-// Author:
-// Marek Sieradzki (marek.sieradzki@gmail.com)
-//
-// (C) 2005 Marek Sieradzki
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-using Microsoft.Build.Logging;
-
-
-using System;
-using System.IO;
-using System.Collections;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Reflection;
-using Microsoft.Build.BuildEngine;
-using Microsoft.Build.Framework;
-using Microsoft.Build.Utilities;
-
-namespace Mono.XBuild.CommandLine {
- public class Parameters {
-
- string consoleLoggerParameters;
- bool displayHelp;
- IList flatArguments;
- IList<LoggerInfo> loggerInfos;
- LoggerVerbosity loggerVerbosity;
- bool noConsoleLogger;
- bool noLogo;
- string projectFile;
- Dictionary<string,string> properties;
- IList remainingArguments;
- Hashtable responseFiles;
- string[] targets;
- bool validate;
- string validationSchema;
- string toolsVersion;
-
- string responseFile;
-
- public Parameters ()
- {
- consoleLoggerParameters = "";
- displayHelp = false;
- loggerInfos = new List<LoggerInfo> ();
- loggerVerbosity = LoggerVerbosity.Normal;
- noConsoleLogger = false;
- noLogo = false;
- properties = new Dictionary<string,string> ();
- targets = new string [0];
-
- responseFile = Path.Combine (
- Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location),
- "msbuild.rsp");
- }
-
- public void ParseArguments (string[] args)
- {
- bool autoResponse = true;
- flatArguments = new ArrayList ();
- remainingArguments = new ArrayList ();
- responseFiles = new Hashtable ();
- FileLoggerParameters = new string[10];
- foreach (string s in args) {
- if (s.StartsWith ("/noautoresponse") || s.StartsWith ("/noautorsp")) {
- autoResponse = false;
- continue;
- }
- if (s [0] != '@') {
- flatArguments.Add (s);
- continue;
- }
- string responseFilename = Path.GetFullPath (UnquoteIfNeeded (s.Substring (1)));
- if (responseFiles.ContainsKey (responseFilename))
- ReportError (1, String.Format ("We already have {0} file.", responseFilename));
- responseFiles [responseFilename] = responseFilename;
- LoadResponseFile (responseFilename);
- }
- if (autoResponse == true) {
- // FIXME: we do not allow nested auto response file
- LoadResponseFile (responseFile);
- }
- foreach (string s in flatArguments) {
- if (s [0] != '/' || !ParseFlatArgument (s))
- remainingArguments.Add (s);
- }
- if (remainingArguments.Count == 0) {
- string[] sln_files = Directory.GetFiles (Directory.GetCurrentDirectory (), "*.sln");
- string[] proj_files = Directory.GetFiles (Directory.GetCurrentDirectory (), "*proj");
-
- if (sln_files.Length == 0 && proj_files.Length == 0)
- ReportError (3, "Please specify the project or solution file " +
- "to build, as none was found in the current directory.");
-
- if (sln_files.Length == 1 && proj_files.Length > 0) {
- var projects_table = new Dictionary<string, string> ();
- foreach (string pfile in SolutionParser.GetAllProjectFileNames (sln_files [0])) {
- string full_path = Path.GetFullPath (pfile);
- projects_table [full_path] = full_path;
- }
-
- if (!proj_files.Any (p => !projects_table.ContainsKey (Path.GetFullPath (p))))
- // if all the project files in the cur dir, are referenced
- // from the single .sln in the cur dir, then pick the sln
- proj_files = new string [0];
- }
-
- if (sln_files.Length + proj_files.Length > 1)
- ReportError (5, "Please specify the project or solution file " +
- "to build, as more than one solution or project file was found " +
- "in the current directory");
-
- if (sln_files.Length == 1)
- projectFile = sln_files [0];
- else
- projectFile = proj_files [0];
- } else if (remainingArguments.Count == 1) {
- projectFile = (string) remainingArguments [0];
- } else {
- ReportError (4, "Too many project files specified");
- }
- }
-
- private string UnquoteIfNeeded(string arg)
- {
- if (arg.StartsWith("\""))
- return arg.Substring(1, arg.Length - 2);
- return arg;
- }
-
- void LoadResponseFile (string filename)
- {
- StreamReader sr = null;
- string line;
- try {
- sr = new StreamReader (filename);
- StringBuilder sb = new StringBuilder ();
-
- while ((line = sr.ReadLine ()) != null) {
- int t = line.Length;
-
- for (int i = 0; i < t; i++) {
- char c = line [i];
-
- if (c == '#')
- // comment, ignore rest of the line
- break;
-
- if (c == '"' || c == '\'') {
- char end = c;
-
- for (i++; i < t; i++) {
- c = line [i];
-
- if (c == end)
- break;
- sb.Append (c);
- }
- } else if (c == ' ') {
- if (sb.Length > 0) {
- flatArguments.Add (sb.ToString ());
- sb.Length = 0;
- }
- } else
- sb.Append (c);
- }
- if (sb.Length > 0){
- flatArguments.Add (sb.ToString ());
- sb.Length = 0;
- }
- }
- } catch (IOException x) {
- ErrorUtilities.ReportWarning (2, String.Format (
- "Error loading response file. (Exception: {0}). Ignoring.",
- x.Message));
- } finally {
- if (sr != null)
- sr.Close ();
- }
- }
-
- private bool ParseFlatArgument (string s)
- {
- switch (s) {
- case "/help":
- case "/h":
- case "/?":
- ErrorUtilities.ShowUsage ();
- break;
- case "/nologo":
- noLogo = true;
- break;
- case "/version":
- case "/ver":
- ErrorUtilities.ShowVersion (true);
- break;
- case "/noconsolelogger":
- case "/noconlog":
- noConsoleLogger = true;
- break;
- case "/validate":
- case "/val":
- validate = true;
- break;
- case "/fl":
- case "/filelogger":
- if (FileLoggerParameters [0] == null)
- FileLoggerParameters [0] = String.Empty;
- break;
- default:
- if (s.StartsWith ("/fl") && s.Length == 4 && Char.IsDigit (s[3])) {
- int index = Int32.Parse (s[3].ToString ());
- if (FileLoggerParameters [index] == null)
- FileLoggerParameters [index] = String.Empty;
- } else if (s.StartsWith ("/fileloggerparameters") || s.StartsWith ("/flp")) {
- ProcessFileLoggerParameters (s);
- } else if (s.StartsWith ("/target:") || s.StartsWith ("/t:")) {
- ProcessTarget (s);
- } else if (s.StartsWith ("/property:") || s.StartsWith ("/p:")) {
- if (!ProcessProperty (s))
- return false;
- } else if (s.StartsWith ("/logger:") || s.StartsWith ("/l:")) {
- ProcessLogger (s);
- } else if (s.StartsWith ("/verbosity:") || s.StartsWith ("/v:")) {
- ProcessVerbosity (s);
- } else if (s.StartsWith ("/consoleloggerparameters:") || s.StartsWith ("/clp:")) {
- ProcessConsoleLoggerParameters (s);
- } else if (s.StartsWith ("/validate:") || s.StartsWith ("/val:")) {
- ProcessValidate (s);
- } else if (s.StartsWith ("/toolsversion:") || s.StartsWith ("/tv:")) {
- ToolsVersion = s.Split (':') [1];
- } else
- return false;
- break;
- }
-
- return true;
- }
-
- internal void ProcessTarget (string s)
- {
- TryProcessMultiOption (s, "Target names must be specified as /t:Target1;Target2",
- out targets);
- }
-
- internal bool ProcessProperty (string s)
- {
- string[] splitProperties;
- if (!TryProcessMultiOption (s, "Property name and value expected as /p:<prop name>=<prop value>",
- out splitProperties))
- return false;
-
- foreach (string st in splitProperties) {
- if (st.IndexOf ('=') < 0) {
- ReportError (5,
- "Invalid syntax. Property name and value expected as " +
- "<prop name>=[<prop value>]");
- return false;
- }
- string [] property = st.Split ('=');
- properties.Add (property [0], property.Length == 2 ? property [1] : "");
- }
-
- return true;
- }
-
- bool TryProcessMultiOption (string s, string error_message, out string[] values)
- {
- values = null;
- int colon = s.IndexOf (':');
- if (colon + 1 == s.Length) {
- ReportError (5, error_message);
- return false;
- }
-
- values = s.Substring (colon + 1).Split (';');
- return true;
- }
-
- private void ReportError (int errorCode, string message)
- {
- throw new CommandLineException (message, errorCode);
- }
-
- private void ReportError (int errorCode, string message, Exception cause)
- {
- throw new CommandLineException (message, cause, errorCode);
- }
-
- internal void ProcessLogger (string s)
- {
- loggerInfos.Add (new LoggerInfo (s));
- }
-
- internal void ProcessVerbosity (string s)
- {
- string[] temp = s.Split (':');
- switch (temp [1]) {
- case "q":
- case "quiet":
- loggerVerbosity = LoggerVerbosity.Quiet;
- break;
- case "m":
- case "minimal":
- loggerVerbosity = LoggerVerbosity.Minimal;
- break;
- case "n":
- case "normal":
- loggerVerbosity = LoggerVerbosity.Normal;
- break;
- case "d":
- case "detailed":
- loggerVerbosity = LoggerVerbosity.Detailed;
- break;
- case "diag":
- case "diagnostic":
- loggerVerbosity = LoggerVerbosity.Diagnostic;
- break;
- }
- }
-
- void ProcessFileLoggerParameters (string s)
- {
- int colon = s.IndexOf (':');
- if (colon + 1 == s.Length)
- ReportError (5, "Invalid syntax, specify parameters as /fileloggerparameters[n]:parameters");
-
- int index = 0;
- string key = s.Substring (0, colon);
- if (Char.IsDigit (key [key.Length - 1]))
- //if (key.Length == 22 && Char.IsDigit (key [21]))
- index = Int32.Parse (key [key.Length - 1].ToString ());
-
- FileLoggerParameters [index] = s.Substring (colon + 1);
- }
-
- internal void ProcessConsoleLoggerParameters (string s)
- {
- int colon = s.IndexOf (':');
- if (colon + 1 == s.Length)
- ReportError (5, "Invalid syntax, specify parameters as /clp:parameters");
-
- consoleLoggerParameters = s.Substring (colon + 1);
- }
-
- internal void ProcessValidate (string s)
- {
- string[] temp;
- validate = true;
- temp = s.Split (':');
- validationSchema = temp [1];
- }
- public bool DisplayHelp {
- get { return displayHelp; }
- }
-
- public bool NoLogo {
- get { return noLogo; }
- }
-
- public string ProjectFile {
- get { return projectFile; }
- }
-
- public string[] Targets {
- get { return targets; }
- }
-
- public Dictionary<string,string> Properties {
- get { return properties; }
- }
-
- IList<ILogger> loggers;
- public IList<ILogger> Loggers {
- get {
- if (loggers == null)
- loggers = loggerInfos.Select (li => new LoggerDescription (li.ClassName, li.AssemblyNameString, li.Filename, li.Parameters, LoggerVerbosity).CreateLogger ()).ToArray ();
- return loggers;
- }
- }
-
- public LoggerVerbosity LoggerVerbosity {
- get { return loggerVerbosity; }
- }
-
- public string ConsoleLoggerParameters {
- get { return consoleLoggerParameters; }
- }
-
- public bool NoConsoleLogger {
- get { return noConsoleLogger; }
- }
-
- public string[] FileLoggerParameters { get; set; }
-
- public bool Validate {
- get { return validate; }
- }
-
- public string ValidationSchema {
- get { return validationSchema; }
- }
-
- public string ToolsVersion {
- get { return toolsVersion; }
- private set { toolsVersion = value; }
- }
-
- }
-}
-
+++ /dev/null
-//
-// SolutionParser.cs: Generates a project file from a solution file.
-//
-// Author:
-// Jonathan Chambers (joncham@gmail.com)
-// Ankit Jain <jankit@novell.com>
-// Lluis Sanchez Gual <lluis@novell.com>
-//
-// (C) 2009 Jonathan Chambers
-// Copyright 2008, 2009 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.IO;
-using Microsoft.Build.Evaluation;
-using Microsoft.Build.Execution;
-using Microsoft.Build.Construction;
-using Microsoft.Build.Exceptions;
-using System.Xml;
-
-namespace Mono.XBuild.CommandLine {
- class ProjectInfo {
- public string Name;
- public string FileName;
- public Guid Guid;
-
- public ProjectInfo (string name, string fileName)
- {
- Name = name;
- FileName = fileName;
- }
-
- public Dictionary<TargetInfo, TargetInfo> TargetMap = new Dictionary<TargetInfo, TargetInfo> ();
- public Dictionary<Guid, ProjectInfo> Dependencies = new Dictionary<Guid, ProjectInfo> ();
- public Dictionary<string, ProjectSection> ProjectSections = new Dictionary<string, ProjectSection> ();
- public List<string> AspNetConfigurations = new List<string> ();
- }
-
- class ProjectSection {
- public string Name;
- public Dictionary<string, string> Properties = new Dictionary<string, string> ();
-
- public ProjectSection (string name)
- {
- Name = name;
- }
- }
-
- struct TargetInfo {
- public string Configuration;
- public string Platform;
- public bool Build;
-
- public TargetInfo (string configuration, string platform)
- : this (configuration, platform, false)
- {
- }
-
- public TargetInfo (string configuration, string platform, bool build)
- {
- Configuration = configuration;
- Platform = platform;
- Build = build;
- }
- }
-
-
- internal delegate void RaiseWarningHandler (int errorNumber, string message);
-
- class SolutionParser {
- static string[] buildTargets = new string[] { "Build", "Clean", "Rebuild", "Publish" };
-
- static string guidExpression = "{[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}}";
-
- static Regex slnVersionRegex = new Regex (@"Microsoft Visual Studio Solution File, Format Version (\d?\d.\d\d)");
- static Regex projectRegex = new Regex ("Project\\(\"(" + guidExpression + ")\"\\) = \"(.*?)\", \"(.*?)\", \"(" + guidExpression + ")\"(\\s*?)((\\s*?)ProjectSection\\((.*?)\\) = (.*?)EndProjectSection(\\s*?))*(\\s*?)(EndProject)?", RegexOptions.Singleline);
- static Regex projectDependenciesRegex = new Regex ("ProjectSection\\((.*?)\\) = \\w*(.*?)EndProjectSection", RegexOptions.Singleline);
- static Regex projectDependencyRegex = new Regex ("\\s*(" + guidExpression + ") = (" + guidExpression + ")");
- static Regex projectSectionPropertiesRegex = new Regex ("\\s*(?<name>.*) = \"(?<value>.*)\"");
-
- static Regex globalRegex = new Regex ("Global(.*)EndGlobal", RegexOptions.Singleline);
- static Regex globalSectionRegex = new Regex ("GlobalSection\\((.*?)\\) = \\w*(.*?)EndGlobalSection", RegexOptions.Singleline);
-
- static Regex solutionConfigurationRegex = new Regex ("\\s*(.*?)\\|(.*?) = (.*?)\\|(.+)");
- static Regex projectConfigurationActiveCfgRegex = new Regex ("\\s*(" + guidExpression + ")\\.(.+?)\\|(.+?)\\.ActiveCfg = (.+?)\\|(.+)");
- static Regex projectConfigurationBuildRegex = new Regex ("\\s*(" + guidExpression + ")\\.(.*?)\\|(.*?)\\.Build\\.0 = (.*?)\\|(.+)");
-
- static string solutionFolderGuid = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}";
- static string vcprojGuid = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}";
- static string websiteProjectGuid = "{E24C65DC-7377-472B-9ABA-BC803B73C61A}";
-
- RaiseWarningHandler RaiseWarning;
-
- public void ParseSolution (string file, ProjectCollection projects, ProjectRootElement p, RaiseWarningHandler RaiseWarning)
- {
- this.RaiseWarning = RaiseWarning;
- EmitBeforeImports (p, file);
-
- AddGeneralSettings (file, p);
-
- StreamReader reader = new StreamReader (file);
- string slnVersion = GetSlnFileVersion (reader);
- if (slnVersion == "12.00")
-#if XBUILD_12
- projects.DefaultToolsVersion = "12.0";
-#else
- projects.DefaultToolsVersion = "4.0";
-#endif
- else if (slnVersion == "11.00")
- projects.DefaultToolsVersion = "4.0";
- else if (slnVersion == "10.00")
- projects.DefaultToolsVersion = "3.5";
- else
- projects.DefaultToolsVersion = "2.0";
-
- string line = reader.ReadToEnd ();
- line = line.Replace ("\r\n", "\n");
- string solutionDir = Path.GetDirectoryName (file);
-
- List<TargetInfo> solutionTargets = new List<TargetInfo> ();
- Dictionary<Guid, ProjectInfo> projectInfos = new Dictionary<Guid, ProjectInfo> ();
- Dictionary<Guid, ProjectInfo> websiteProjectInfos = new Dictionary<Guid, ProjectInfo> ();
- List<ProjectInfo>[] infosByLevel = null;
- Dictionary<Guid, ProjectInfo> unsupportedProjectInfos = new Dictionary<Guid, ProjectInfo> ();
-
- Match m = projectRegex.Match (line);
- while (m.Success) {
- ProjectInfo projectInfo = new ProjectInfo (m.Groups[2].Value,
- Path.GetFullPath (Path.Combine (solutionDir,
- m.Groups [3].Value.Replace ('\\', Path.DirectorySeparatorChar))));
- if (String.Compare (m.Groups [1].Value, solutionFolderGuid,
- StringComparison.InvariantCultureIgnoreCase) == 0) {
- // Ignore solution folders
- m = m.NextMatch ();
- continue;
- }
-
- projectInfo.Guid = new Guid (m.Groups [4].Value);
-
- if (String.Compare (m.Groups [1].Value, vcprojGuid,
- StringComparison.InvariantCultureIgnoreCase) == 0) {
- // Ignore vcproj
- RaiseWarning (0, string.Format("Ignoring vcproj '{0}'.", projectInfo.Name));
-
- unsupportedProjectInfos [projectInfo.Guid] = projectInfo;
- m = m.NextMatch ();
- continue;
- }
-
- if (String.Compare (m.Groups [1].Value, websiteProjectGuid,
- StringComparison.InvariantCultureIgnoreCase) == 0)
- websiteProjectInfos.Add (new Guid (m.Groups[4].Value), projectInfo);
- else
- projectInfos.Add (projectInfo.Guid, projectInfo);
-
- Match projectSectionMatch = projectDependenciesRegex.Match (m.Groups[6].Value);
- while (projectSectionMatch.Success) {
- string section_name = projectSectionMatch.Groups [1].Value;
- if (String.Compare (section_name, "ProjectDependencies") == 0) {
- Match projectDependencyMatch = projectDependencyRegex.Match (projectSectionMatch.Value);
- while (projectDependencyMatch.Success) {
- // we might not have projectInfo available right now, so
- // set it to null, and fill it in later
- projectInfo.Dependencies [new Guid (projectDependencyMatch.Groups[1].Value)] = null;
- projectDependencyMatch = projectDependencyMatch.NextMatch ();
- }
- } else {
- ProjectSection section = new ProjectSection (section_name);
- Match propertiesMatch = projectSectionPropertiesRegex.Match (
- projectSectionMatch.Groups [2].Value);
- while (propertiesMatch.Success) {
- section.Properties [propertiesMatch.Groups ["name"].Value] =
- propertiesMatch.Groups ["value"].Value;
-
- propertiesMatch = propertiesMatch.NextMatch ();
- }
-
- projectInfo.ProjectSections [section_name] = section;
- }
- projectSectionMatch = projectSectionMatch.NextMatch ();
- }
- m = m.NextMatch ();
- }
-
- foreach (ProjectInfo projectInfo in projectInfos.Values) {
- string filename = projectInfo.FileName;
- string projectDir = Path.GetDirectoryName (filename);
-
- if (!File.Exists (filename)) {
- RaiseWarning (0, String.Format ("Project file {0} referenced in the solution file, " +
- " not found. Ignoring.", filename));
- continue;
- }
-
- Project currentProject;
- try {
- using (var xmlReader = XmlReader.Create (filename)) {
- var root = ProjectRootElement.Create (xmlReader, projects);
- root.FullPath = filename;
- currentProject = new Project (root, null, null, projects, ProjectLoadSettings.IgnoreMissingImports);
- }
- } catch (InvalidProjectFileException e) {
- RaiseWarning (0, e.Message);
- continue;
- }
-
- foreach (var bi in currentProject.GetItems ("ProjectReference")) {
- ProjectInfo info = null;
- string projectReferenceGuid = bi.GetMetadataValue ("Project");
- bool hasGuid = !String.IsNullOrEmpty (projectReferenceGuid);
-
- // try to resolve the ProjectReference by GUID
- // and fallback to project filename
-
- if (hasGuid) {
- Guid guid = new Guid (projectReferenceGuid);
- projectInfos.TryGetValue (guid, out info);
- if (info == null && unsupportedProjectInfos.TryGetValue (guid, out info)) {
- RaiseWarning (0, String.Format (
- "{0}: ProjectReference '{1}' is of an unsupported type. Ignoring.",
- filename, bi.EvaluatedInclude));
- continue;
- }
- }
-
- if (info == null || !hasGuid) {
- // Project not found by guid or guid not available
- // Try to find by project file
-
- string fullpath = Path.GetFullPath (Path.Combine (projectDir, bi.EvaluatedInclude.Replace ('\\', Path.DirectorySeparatorChar)));
- info = projectInfos.Values.FirstOrDefault (pi => pi.FileName == fullpath);
-
- if (info == null) {
- if (unsupportedProjectInfos.Values.Any (pi => pi.FileName == fullpath))
- RaiseWarning (0, String.Format (
- "{0}: ProjectReference '{1}' is of an unsupported type. Ignoring.",
- filename, bi.EvaluatedInclude));
- else
- RaiseWarning (0, String.Format (
- "{0}: ProjectReference '{1}' not found, neither by guid '{2}' nor by project file name '{3}'.",
- filename, bi.EvaluatedInclude, projectReferenceGuid.Replace ("{", "").Replace ("}", ""), fullpath));
- }
-
- }
-
- if (info != null)
- projectInfo.Dependencies [info.Guid] = info;
- }
- }
-
- // fill in the project info for deps found in the .sln file
- foreach (ProjectInfo projectInfo in projectInfos.Values) {
- List<Guid> missingInfos = new List<Guid> ();
- foreach (KeyValuePair<Guid, ProjectInfo> dependency in projectInfo.Dependencies) {
- if (dependency.Value == null)
- missingInfos.Add (dependency.Key);
- }
-
- foreach (Guid guid in missingInfos) {
- ProjectInfo info;
- if (projectInfos.TryGetValue (guid, out info))
- projectInfo.Dependencies [guid] = info;
- else
- projectInfo.Dependencies.Remove (guid);
- }
- }
-
- Match globalMatch = globalRegex.Match (line);
- Match globalSectionMatch = globalSectionRegex.Match (globalMatch.Groups[1].Value);
- while (globalSectionMatch.Success) {
- string sectionType = globalSectionMatch.Groups[1].Value;
- switch (sectionType) {
- case "SolutionConfigurationPlatforms":
- ParseSolutionConfigurationPlatforms (globalSectionMatch.Groups[2].Value, solutionTargets);
- break;
- case "ProjectConfigurationPlatforms":
- ParseProjectConfigurationPlatforms (globalSectionMatch.Groups[2].Value,
- projectInfos, websiteProjectInfos);
- break;
- case "SolutionProperties":
- ParseSolutionProperties (globalSectionMatch.Groups[2].Value);
- break;
- case "NestedProjects":
- break;
- case "MonoDevelopProperties":
- break;
- default:
- RaiseWarning (0, string.Format("Don't know how to handle GlobalSection {0}, Ignoring.", sectionType));
- break;
- }
- globalSectionMatch = globalSectionMatch.NextMatch ();
- }
-
- int num_levels = AddBuildLevels (p, solutionTargets, projectInfos, ref infosByLevel);
-
- AddCurrentSolutionConfigurationContents (p, solutionTargets, projectInfos, websiteProjectInfos);
- AddProjectReferences (p, projectInfos);
- AddWebsiteProperties (p, websiteProjectInfos, projectInfos);
- AddValidateSolutionConfiguration (p);
-
- EmitAfterImports (p, file);
-
- AddGetFrameworkPathTarget (p);
- AddWebsiteTargets (p, websiteProjectInfos, projectInfos, infosByLevel, solutionTargets);
- AddProjectTargets (p, solutionTargets, projectInfos);
- AddSolutionTargets (p, num_levels, websiteProjectInfos.Values);
- }
-
- string GetSlnFileVersion (StreamReader reader)
- {
- string strInput = null;
- Match match;
-
- strInput = reader.ReadLine();
- if (strInput == null)
- return null;
-
- match = slnVersionRegex.Match(strInput);
- if (!match.Success) {
- strInput = reader.ReadLine();
- if (strInput == null)
- return null;
- match = slnVersionRegex.Match (strInput);
- }
-
- if (match.Success)
- return match.Groups[1].Value;
-
- return null;
- }
-
- void EmitBeforeImports (ProjectRootElement p, string file)
- {
- p.AddImportGroup ().AddImport ("$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\SolutionFile\\ImportBefore\\*").Condition =
- "'$(ImportByWildcardBeforeSolution)' != 'false' and " +
- "Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\SolutionFile\\ImportBefore')";
-
- string before_filename = Path.Combine (Path.GetDirectoryName (file), "before." + Path.GetFileName (file) + ".targets");
- p.AddImportGroup ().AddImport (before_filename).Condition = String.Format ("Exists ('{0}')", before_filename);
- }
-
- void EmitAfterImports (ProjectRootElement p, string file)
- {
- p.AddImportGroup ().AddImport ("$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\SolutionFile\\ImportAfter\\*").Condition =
- "'$(ImportByWildcardAfterSolution)' != 'false' and " +
- "Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\SolutionFile\\ImportAfter')";
-
- string after_filename = Path.Combine (Path.GetDirectoryName (file), "after." + Path.GetFileName (file) + ".targets");
- p.AddImportGroup ().AddImport (after_filename).Condition = String.Format ("Exists ('{0}')", after_filename);
- }
-
- void AddGeneralSettings (string solutionFile, ProjectRootElement p)
- {
- p.DefaultTargets = "Build";
- p.InitialTargets = "ValidateSolutionConfiguration";
- //p.AddUsingTask ("CreateTemporaryVCProject", null, "Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
- //p.AddUsingTask ("ResolveVCProjectOutput", null, "Microsoft.Build.Tasks, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
-
- string solutionFilePath = Path.GetFullPath (solutionFile);
- var solutionPropertyGroup = p.CreatePropertyGroupElement ();
- //solutionPropertyGroup.ChildrenReversed = true;
- solutionPropertyGroup.AddProperty ("SolutionDir", Path.GetDirectoryName (solutionFilePath) + Path.DirectorySeparatorChar);
- solutionPropertyGroup.AddProperty ("SolutionExt", Path.GetExtension (solutionFile));
- solutionPropertyGroup.AddProperty ("SolutionFileName", Path.GetFileName (solutionFile));
- solutionPropertyGroup.AddProperty ("SolutionName", Path.GetFileNameWithoutExtension (solutionFile));
- solutionPropertyGroup.AddProperty ("SolutionPath", solutionFilePath);
- }
-
- void ParseSolutionConfigurationPlatforms (string section, List<TargetInfo> solutionTargets)
- {
- Match solutionConfigurationPlatform = solutionConfigurationRegex.Match (section);
- while (solutionConfigurationPlatform.Success) {
- string solutionConfiguration = solutionConfigurationPlatform.Groups[1].Value;
- string solutionPlatform = solutionConfigurationPlatform.Groups[2].Value;
- solutionTargets.Add (new TargetInfo (solutionConfiguration, solutionPlatform));
- solutionConfigurationPlatform = solutionConfigurationPlatform.NextMatch ();
- }
- }
-
- // ignores the website projects, in the websiteProjectInfos
- void ParseProjectConfigurationPlatforms (string section, Dictionary<Guid, ProjectInfo> projectInfos,
- Dictionary<Guid, ProjectInfo> websiteProjectInfos)
- {
- List<Guid> missingGuids = new List<Guid> ();
- Match projectConfigurationPlatform = projectConfigurationActiveCfgRegex.Match (section);
- while (projectConfigurationPlatform.Success) {
- Guid guid = new Guid (projectConfigurationPlatform.Groups[1].Value);
- ProjectInfo projectInfo;
- if (!projectInfos.TryGetValue (guid, out projectInfo)) {
- if (!missingGuids.Contains (guid)) {
- if (!websiteProjectInfos.ContainsKey (guid))
- // ignore website projects
- RaiseWarning (0, string.Format("Failed to find project {0}", guid));
- missingGuids.Add (guid);
- }
- projectConfigurationPlatform = projectConfigurationPlatform.NextMatch ();
- continue;
- }
- string solConf = projectConfigurationPlatform.Groups[2].Value;
- string solPlat = projectConfigurationPlatform.Groups[3].Value;
- string projConf = projectConfigurationPlatform.Groups[4].Value;
- string projPlat = projectConfigurationPlatform.Groups[5].Value;
- // hack, what are they doing here?
- if (projPlat == "Any CPU")
- projPlat = "AnyCPU";
- projectInfo.TargetMap.Add (new TargetInfo (solConf, solPlat), new TargetInfo (projConf, projPlat));
- projectConfigurationPlatform = projectConfigurationPlatform.NextMatch ();
- }
- Match projectConfigurationPlatformBuild = projectConfigurationBuildRegex.Match (section);
- while (projectConfigurationPlatformBuild.Success) {
- Guid guid = new Guid (projectConfigurationPlatformBuild.Groups[1].Value);
- ProjectInfo projectInfo;
- if (!projectInfos.TryGetValue (guid, out projectInfo)) {
- if (!missingGuids.Contains (guid)) {
- RaiseWarning (0, string.Format("Failed to find project {0}", guid));
- missingGuids.Add (guid);
- }
- projectConfigurationPlatformBuild = projectConfigurationPlatformBuild.NextMatch ();
- continue;
- }
- string solConf = projectConfigurationPlatformBuild.Groups[2].Value;
- string solPlat = projectConfigurationPlatformBuild.Groups[3].Value;
- string projConf = projectConfigurationPlatformBuild.Groups[4].Value;
- string projPlat = projectConfigurationPlatformBuild.Groups[5].Value;
- // hack, what are they doing here?
- if (projPlat == "Any CPU")
- projPlat = "AnyCPU";
- projectInfo.TargetMap[new TargetInfo (solConf, solPlat)] = new TargetInfo (projConf, projPlat, true);
- projectConfigurationPlatformBuild = projectConfigurationPlatformBuild.NextMatch ();
- }
- }
-
- void ParseSolutionProperties (string section)
- {
- }
-
- void AddCurrentSolutionConfigurationContents (ProjectRootElement p, List<TargetInfo> solutionTargets,
- Dictionary<Guid, ProjectInfo> projectInfos,
- Dictionary<Guid, ProjectInfo> websiteProjectInfos)
- {
- TargetInfo default_target_info = new TargetInfo ("Debug", "Any CPU");
- if (solutionTargets.Count > 0) {
- bool found = false;
- foreach (TargetInfo tinfo in solutionTargets) {
- if (String.Compare (tinfo.Platform, "Mixed Platforms") == 0) {
- default_target_info = tinfo;
- found = true;
- break;
- }
- }
-
- if (!found)
- default_target_info = solutionTargets [0];
- }
-
- AddDefaultSolutionConfiguration (p, default_target_info);
-
- foreach (TargetInfo solutionTarget in solutionTargets) {
- var platformPropertyGroup = p.AddPropertyGroup ();
- platformPropertyGroup.Condition = string.Format (
- " ('$(Configuration)' == '{0}') and ('$(Platform)' == '{1}') ",
- solutionTarget.Configuration,
- solutionTarget.Platform
- );
-
- StringBuilder solutionConfigurationContents = new StringBuilder ();
- solutionConfigurationContents.Append ("<SolutionConfiguration xmlns=\"\">");
- foreach (KeyValuePair<Guid, ProjectInfo> projectInfo in projectInfos) {
- AddProjectConfigurationItems (projectInfo.Key, projectInfo.Value, solutionTarget, solutionConfigurationContents);
- }
- solutionConfigurationContents.Append ("</SolutionConfiguration>");
-
- platformPropertyGroup.AddProperty ("CurrentSolutionConfigurationContents",
- solutionConfigurationContents.ToString ());
- }
- }
-
- void AddProjectReferences (ProjectRootElement p, Dictionary<Guid, ProjectInfo> projectInfos)
- {
- var big = p.AddItemGroup ();
- foreach (KeyValuePair<Guid, ProjectInfo> pair in projectInfos)
- big.AddItem ("ProjectReference", pair.Value.FileName);
- }
-
- void AddProjectConfigurationItems (Guid guid, ProjectInfo projectInfo, TargetInfo solutionTarget,
- StringBuilder solutionConfigurationContents)
- {
- foreach (KeyValuePair<TargetInfo, TargetInfo> targetInfo in projectInfo.TargetMap) {
- if (solutionTarget.Configuration == targetInfo.Key.Configuration &&
- solutionTarget.Platform == targetInfo.Key.Platform) {
- solutionConfigurationContents.AppendFormat (
- "<ProjectConfiguration Project=\"{0}\">{1}|{2}</ProjectConfiguration>",
- guid.ToString ("B").ToUpper (), targetInfo.Value.Configuration, targetInfo.Value.Platform);
- }
- }
- }
-
- void AddDefaultSolutionConfiguration (ProjectRootElement p, TargetInfo target)
- {
- var configurationPropertyGroup = p.AddPropertyGroup ();
- //configurationPropertyGroup.PropertiesReversed = true;
- configurationPropertyGroup.Condition = " '$(Configuration)' == '' ";
- configurationPropertyGroup.AddProperty ("Configuration", target.Configuration);
-
- var platformPropertyGroup = p.AddPropertyGroup ();
- //platformPropertyGroup.PropertiesReversed = true;
- platformPropertyGroup.Condition = " '$(Platform)' == '' ";
- platformPropertyGroup.AddProperty ("Platform", target.Platform);
-
- // emit default for AspNetConfiguration also
- var aspNetConfigurationPropertyGroup = p.AddPropertyGroup ();
- //aspNetConfigurationPropertyGroup.PropertiesReversed = true;
- aspNetConfigurationPropertyGroup.Condition = " ('$(AspNetConfiguration)' == '') ";
- aspNetConfigurationPropertyGroup.AddProperty ("AspNetConfiguration", "$(Configuration)");
- }
-
- void AddWarningForMissingProjectConfiguration (ProjectTargetElement target, string slnConfig, string slnPlatform, string projectName)
- {
- var task = target.AddTask ("Warning");
- task.SetParameter ("Text",
- String.Format ("The project configuration for project '{0}' corresponding " +
- "to the solution configuration '{1}|{2}' was not found in the solution file.",
- projectName, slnConfig, slnPlatform));
- task.Condition = String.Format ("('$(Configuration)' == '{0}') and ('$(Platform)' == '{1}')",
- slnConfig, slnPlatform);
-
- }
-
- // Website project methods
-
- void AddWebsiteProperties (ProjectRootElement p, Dictionary<Guid, ProjectInfo> websiteProjectInfos,
- Dictionary<Guid, ProjectInfo> projectInfos)
- {
- var propertyGroupByConfig = new Dictionary<string, ProjectPropertyGroupElement> ();
- foreach (KeyValuePair<Guid, ProjectInfo> infoPair in websiteProjectInfos) {
- ProjectInfo info = infoPair.Value;
- string projectGuid = infoPair.Key.ToString ();
-
- ProjectSection section;
- if (!info.ProjectSections.TryGetValue ("WebsiteProperties", out section)) {
- RaiseWarning (0, String.Format ("Website project '{0}' does not have the required project section: WebsiteProperties. Ignoring project.", info.Name));
- return;
- }
-
- //parse project references
- string [] ref_guids = null;
- string references;
- if (section.Properties.TryGetValue ("ProjectReferences", out references)) {
- ref_guids = references.Split (new char [] {';'}, StringSplitOptions.RemoveEmptyEntries);
- for (int i = 0; i < ref_guids.Length; i ++) {
- // "{guid}|foo.dll"
- ref_guids [i] = ref_guids [i].Split ('|') [0];
-
- Guid r_guid = new Guid (ref_guids [i]);
- ProjectInfo ref_info;
- if (projectInfos.TryGetValue (r_guid, out ref_info))
- // ignore if not found
- info.Dependencies [r_guid] = ref_info;
- }
- }
-
- foreach (KeyValuePair<string, string> pair in section.Properties) {
- //looking for -- ConfigName.AspNetCompiler.PropName
- string [] parts = pair.Key.Split ('.');
- if (parts.Length != 3 || String.Compare (parts [1], "AspNetCompiler") != 0)
- continue;
-
- string config = parts [0];
- string propertyName = parts [2];
-
- ProjectPropertyGroupElement bpg;
- if (!propertyGroupByConfig.TryGetValue (config, out bpg)) {
- bpg = p.AddPropertyGroup ();
- //bpg.PropertiesReversed = true;
- bpg.Condition = String.Format (" '$(AspNetConfiguration)' == '{0}' ", config);
- propertyGroupByConfig [config] = bpg;
- }
-
- bpg.AddProperty (String.Format ("Project_{0}_AspNet{1}", projectGuid, propertyName),
- pair.Value);
-
- if (!info.AspNetConfigurations.Contains (config))
- info.AspNetConfigurations.Add (config);
- }
- }
- }
-
- // For WebSite projects
- // The main "Build" target:
- // 1. builds all non-website projects
- // 2. calls target for website project
- // - gets target path for the referenced projects
- // - Resolves dependencies, satellites etc for the
- // referenced project assemblies, and copies them
- // to bin/ folder
- void AddWebsiteTargets (ProjectRootElement p, Dictionary<Guid, ProjectInfo> websiteProjectInfos,
- Dictionary<Guid, ProjectInfo> projectInfos, List<ProjectInfo>[] infosByLevel,
- List<TargetInfo> solutionTargets)
- {
- foreach (ProjectInfo w_info in websiteProjectInfos.Values) {
- // gets a linear list of dependencies
- List<ProjectInfo> depInfos = new List<ProjectInfo> ();
- foreach (List<ProjectInfo> pinfos in infosByLevel) {
- foreach (ProjectInfo pinfo in pinfos)
- if (w_info.Dependencies.ContainsKey (pinfo.Guid))
- depInfos.Add (pinfo);
- }
-
- foreach (string buildTarget in new string [] {"Build", "Rebuild"})
- AddWebsiteTarget (p, w_info, projectInfos, depInfos, solutionTargets, buildTarget);
-
- // clean/publish are not supported for website projects
- foreach (string buildTarget in new string [] {"Clean", "Publish"})
- AddWebsiteUnsupportedTarget (p, w_info, depInfos, buildTarget);
- }
- }
-
- void AddWebsiteTarget (ProjectRootElement p, ProjectInfo webProjectInfo,
- Dictionary<Guid, ProjectInfo> projectInfos, List<ProjectInfo> depInfos,
- List<TargetInfo> solutionTargets, string buildTarget)
- {
- string w_guid = webProjectInfo.Guid.ToString ().ToUpper ();
-
- var target = p.AddTarget (GetTargetNameForProject (webProjectInfo.Name, buildTarget));
- target.Condition = "'$(CurrentSolutionConfigurationContents)' != ''";
- target.DependsOnTargets = GetWebsiteDependsOnTarget (depInfos, buildTarget);
-
- // this item collects all the references
- string final_ref_item = String.Format ("Project_{0}_References{1}", w_guid,
- buildTarget != "Build" ? "_" + buildTarget : String.Empty);
-
- foreach (TargetInfo targetInfo in solutionTargets) {
- int ref_num = 0;
- foreach (ProjectInfo depInfo in depInfos) {
- TargetInfo projectTargetInfo;
- if (!depInfo.TargetMap.TryGetValue (targetInfo, out projectTargetInfo))
- // Ignore, no config, so no target path
- continue;
-
- // GetTargetPath from the referenced project
- AddWebsiteMSBuildTaskForReference (target, depInfo, projectTargetInfo, targetInfo,
- final_ref_item, ref_num);
- ref_num ++;
- }
- }
-
- // resolve the references
- AddWebsiteResolveAndCopyReferencesTasks (target, webProjectInfo, final_ref_item, w_guid);
- }
-
- // emits the MSBuild task to GetTargetPath for the referenced project
- void AddWebsiteMSBuildTaskForReference (ProjectTargetElement target, ProjectInfo depInfo, TargetInfo projectTargetInfo,
- TargetInfo solutionTargetInfo, string final_ref_item, int ref_num)
- {
- var task = target.AddTask ("MSBuild");
- task.SetParameter ("Projects", depInfo.FileName);
- task.SetParameter ("Targets", "GetTargetPath");
-
- task.SetParameter ("Properties", string.Format ("Configuration={0}; Platform={1}; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)", projectTargetInfo.Configuration, projectTargetInfo.Platform));
- task.Condition = string.Format (" ('$(Configuration)' == '{0}') and ('$(Platform)' == '{1}') ", solutionTargetInfo.Configuration, solutionTargetInfo.Platform);
-
- string ref_item = String.Format ("{0}_{1}",
- final_ref_item, ref_num);
-
- task.AddOutputItem ("TargetOutputs", ref_item);
-
- task = target.AddTask ("CreateItem");
- task.SetParameter ("Include", String.Format ("@({0})", ref_item));
- task.SetParameter ("AdditionalMetadata", String.Format ("Guid={{{0}}}",
- depInfo.Guid.ToString ().ToUpper ()));
- task.AddOutputItem ("Include", final_ref_item);
- }
-
- void AddWebsiteResolveAndCopyReferencesTasks (ProjectTargetElement target, ProjectInfo webProjectInfo,
- string final_ref_item, string w_guid)
- {
- var task = target.AddTask ("ResolveAssemblyReference");
- task.SetParameter ("Assemblies", String.Format ("@({0}->'%(FullPath)')", final_ref_item));
- task.SetParameter ("TargetFrameworkDirectories", "$(TargetFrameworkPath)");
- task.SetParameter ("SearchPaths", "{RawFileName};{TargetFrameworkDirectory};{GAC}");
- task.SetParameter ("FindDependencies", "true");
- task.SetParameter ("FindSatellites", "true");
- task.SetParameter ("FindRelatedFiles", "true");
- task.Condition = String.Format ("Exists ('%({0}.Identity)')", final_ref_item);
-
- string copylocal_item = String.Format ("{0}_CopyLocalFiles", final_ref_item);
- task.AddOutputItem ("CopyLocalFiles", copylocal_item);
-
- // Copy the references
- task = target.AddTask ("Copy");
- task.SetParameter ("SourceFiles", String.Format ("@({0})", copylocal_item));
- task.SetParameter ("DestinationFiles", String.Format (
- "@({0}->'$(Project_{1}_AspNetPhysicalPath)\\Bin\\%(DestinationSubDirectory)%(Filename)%(Extension)')",
- copylocal_item, w_guid));
-
- // AspNetConfiguration, is config for the website project, useful
- // for overriding from command line
- StringBuilder cond = new StringBuilder ();
- foreach (string config in webProjectInfo.AspNetConfigurations) {
- if (cond.Length > 0)
- cond.Append (" or ");
- cond.AppendFormat (" ('$(AspNetConfiguration)' == '{0}') ", config);
- }
- task.Condition = cond.ToString ();
-
- task = target.AddTask ("Message");
- cond = new StringBuilder ();
- foreach (string config in webProjectInfo.AspNetConfigurations) {
- if (cond.Length > 0)
- cond.Append (" and ");
- cond.AppendFormat (" ('$(AspNetConfiguration)' != '{0}') ", config);
- }
- task.Condition = cond.ToString ();
- task.SetParameter ("Text", "Skipping as the '$(AspNetConfiguration)' configuration is " +
- "not supported by this website project.");
- }
-
- void AddWebsiteUnsupportedTarget (ProjectRootElement p, ProjectInfo webProjectInfo, List<ProjectInfo> depInfos,
- string buildTarget)
- {
- var target = p.AddTarget (GetTargetNameForProject (webProjectInfo.Name, buildTarget));
- target.DependsOnTargets = GetWebsiteDependsOnTarget (depInfos, buildTarget);
-
- var task = target.AddTask ("Message");
- task.SetParameter ("Text", String.Format (
- "Target '{0}' not support for website projects", buildTarget));
- }
-
- string GetWebsiteDependsOnTarget (List<ProjectInfo> depInfos, string buildTarget)
- {
- StringBuilder deps = new StringBuilder ();
- foreach (ProjectInfo pinfo in depInfos) {
- if (deps.Length > 0)
- deps.Append (";");
- deps.Append (GetTargetNameForProject (pinfo.Name, buildTarget));
- }
- deps.Append (";GetFrameworkPath");
- return deps.ToString ();
- }
-
- void AddGetFrameworkPathTarget (ProjectRootElement p)
- {
- var t = p.AddTarget ("GetFrameworkPath");
- var task = t.AddTask ("GetFrameworkPath");
- task.AddOutputProperty ("Path", "TargetFrameworkPath");
- }
-
- void AddValidateSolutionConfiguration (ProjectRootElement p)
- {
- var t = p.AddTarget ("ValidateSolutionConfiguration");
- var task = t.AddTask ("Warning");
- task.SetParameter ("Text", "On windows, an environment variable 'Platform' is set to MCD sometimes, and this overrides the Platform property" +
- " for Mono msbuild, which could be an invalid Platform for this solution file. And so you are getting the following error." +
- " You could override it by either setting the environment variable to nothing, as\n" +
- " set Platform=\n" +
- "Or explicity specify its value on the command line, as\n" +
- " msbuild Foo.sln /p:Platform=Release");
- task.Condition = "('$(CurrentSolutionConfigurationContents)' == '') and ('$(SkipInvalidConfigurations)' != 'true')" +
- " and '$(Platform)' == 'MCD' and '$(OS)' == 'Windows_NT'";
-
- task = t.AddTask ("Error");
- task.SetParameter ("Text", "Invalid solution configuration and platform: \"$(Configuration)|$(Platform)\".");
- task.Condition = "('$(CurrentSolutionConfigurationContents)' == '') and ('$(SkipInvalidConfigurations)' != 'true')";
- task = t.AddTask ("Warning");
- task.SetParameter ("Text", "Invalid solution configuration and platform: \"$(Configuration)|$(Platform)\".");
- task.Condition = "('$(CurrentSolutionConfigurationContents)' == '') and ('$(SkipInvalidConfigurations)' == 'true')";
- task = t.AddTask ("Message");
- task.SetParameter ("Text", "Building solution configuration \"$(Configuration)|$(Platform)\".");
- task.Condition = "'$(CurrentSolutionConfigurationContents)' != ''";
- }
-
- void AddProjectTargets (ProjectRootElement p, List<TargetInfo> solutionTargets, Dictionary<Guid, ProjectInfo> projectInfos)
- {
- foreach (KeyValuePair<Guid, ProjectInfo> projectInfo in projectInfos) {
- ProjectInfo project = projectInfo.Value;
- foreach (string buildTarget in buildTargets) {
- string target_name = GetTargetNameForProject (project.Name, buildTarget);
- bool is_build_or_rebuild = buildTarget == "Build" || buildTarget == "Rebuild";
- var target = p.AddTarget (target_name);
- target.Condition = "'$(CurrentSolutionConfigurationContents)' != ''";
-
- if (is_build_or_rebuild)
- target.Outputs = "@(CollectedBuildOutput)";
- if (project.Dependencies.Count > 0)
- target.DependsOnTargets = String.Join (";",
- project.Dependencies.Values.Select (
- di => GetTargetNameForProject (di.Name, buildTarget)).ToArray ());
-
- foreach (TargetInfo targetInfo in solutionTargets) {
- ProjectTaskElement task = null;
- TargetInfo projectTargetInfo;
- if (!project.TargetMap.TryGetValue (targetInfo, out projectTargetInfo)) {
- AddWarningForMissingProjectConfiguration (target, targetInfo.Configuration,
- targetInfo.Platform, project.Name);
- continue;
- }
- if (projectTargetInfo.Build) {
- task = target.AddTask ("MSBuild");
- task.SetParameter ("Projects", project.FileName);
- task.SetParameter ("ToolsVersion", "$(ProjectToolsVersion)");
- if (is_build_or_rebuild)
- task.AddOutputItem ("TargetOutputs", "CollectedBuildOutput");
-
- if (buildTarget != "Build")
- task.SetParameter ("Targets", buildTarget);
- task.SetParameter ("Properties", string.Format ("Configuration={0}; Platform={1}; BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)", projectTargetInfo.Configuration, projectTargetInfo.Platform));
- } else {
- task = target.AddTask ("Message");
- task.SetParameter ("Text", string.Format ("Project \"{0}\" is disabled for solution configuration \"{1}|{2}\".", project.Name, targetInfo.Configuration, targetInfo.Platform));
- }
- task.Condition = string.Format (" ('$(Configuration)' == '{0}') and ('$(Platform)' == '{1}') ", targetInfo.Configuration, targetInfo.Platform);
- }
- }
- }
- }
-
-
- string GetTargetNameForProject (string projectName, string buildTarget)
- {
- //FIXME: hack
- projectName = projectName.Replace ("\\", "/").Replace (".", "_");
- string target_name = projectName +
- (buildTarget == "Build" ? string.Empty : ":" + buildTarget);
-
- if (IsBuildTargetName (projectName))
- target_name = "Solution:" + target_name;
-
- return target_name;
- }
-
- bool IsBuildTargetName (string name)
- {
- foreach (string tgt in buildTargets)
- if (name == tgt)
- return true;
- return false;
- }
-
- // returns number of levels
- int AddBuildLevels (ProjectRootElement p, List<TargetInfo> solutionTargets, Dictionary<Guid, ProjectInfo> projectInfos,
- ref List<ProjectInfo>[] infosByLevel)
- {
- infosByLevel = TopologicalSort<ProjectInfo> (projectInfos.Values);
-
- foreach (TargetInfo targetInfo in solutionTargets) {
- var big = p.AddItemGroup ();
- big.Condition = String.Format (" ('$(Configuration)' == '{0}') and ('$(Platform)' == '{1}') ",
- targetInfo.Configuration, targetInfo.Platform);
-
- //FIXME: every level has projects that can be built in parallel.
- // levels are ordered on the basis of the dependency graph
-
- for (int i = 0; i < infosByLevel.Length; i ++) {
- string build_level = String.Format ("BuildLevel{0}", i);
- string skip_level = String.Format ("SkipLevel{0}", i);
- string missing_level = String.Format ("MissingConfigLevel{0}", i);
-
- foreach (ProjectInfo projectInfo in infosByLevel [i]) {
- TargetInfo projectTargetInfo;
- if (!projectInfo.TargetMap.TryGetValue (targetInfo, out projectTargetInfo)) {
- // missing project config
- big.AddItem (missing_level, projectInfo.Name);
- continue;
- }
-
- if (projectTargetInfo.Build) {
- var item = big.AddItem (build_level, projectInfo.FileName);
- item.AddMetadata ("Configuration", projectTargetInfo.Configuration);
- item.AddMetadata ("Platform", projectTargetInfo.Platform);
- } else {
- // build disabled
- big.AddItem (skip_level, projectInfo.Name);
- }
- }
- }
- }
-
- return infosByLevel.Length;
- }
-
- void AddSolutionTargets (ProjectRootElement p, int num_levels, IEnumerable<ProjectInfo> websiteProjectInfos)
- {
- foreach (string buildTarget in buildTargets) {
- var t = p.AddTarget (buildTarget);
- bool is_build_or_rebuild = buildTarget == "Build" || buildTarget == "Rebuild";
-
- t.Condition = "'$(CurrentSolutionConfigurationContents)' != ''";
- if (is_build_or_rebuild)
- t.Outputs = "@(CollectedBuildOutput)";
-
- ProjectTaskElement task = null;
- for (int i = 0; i < num_levels; i ++) {
- string level_str = String.Format ("BuildLevel{0}", i);
- task = t.AddTask ("MSBuild");
- task.SetParameter ("Condition", String.Format ("'@({0})' != ''", level_str));
- task.SetParameter ("Projects", String.Format ("@({0})", level_str));
- task.SetParameter ("ToolsVersion", "$(ProjectToolsVersion)");
- task.SetParameter ("Properties",
- string.Format ("Configuration=%(Configuration); Platform=%(Platform); BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)"));
- if (buildTarget != "Build")
- task.SetParameter ("Targets", buildTarget);
- //FIXME: change this to BuildInParallel=true, when parallel
- // build support gets added
- task.SetParameter ("RunEachTargetSeparately", "true");
- if (is_build_or_rebuild)
- task.AddOutputItem ("TargetOutputs", "CollectedBuildOutput");
-
- level_str = String.Format ("SkipLevel{0}", i);
- task = t.AddTask ("Message");
- task.Condition = String.Format ("'@({0})' != ''", level_str);
- task.SetParameter ("Text",
- String.Format ("The project '%({0}.Identity)' is disabled for solution " +
- "configuration '$(Configuration)|$(Platform)'.", level_str));
-
- level_str = String.Format ("MissingConfigLevel{0}", i);
- task = t.AddTask ("Warning");
- task.Condition = String.Format ("'@({0})' != ''", level_str);
- task.SetParameter ("Text",
- String.Format ("The project configuration for project '%({0}.Identity)' " +
- "corresponding to the solution configuration " +
- "'$(Configuration)|$(Platform)' was not found.", level_str));
- }
-
- // "build" website projects also
- StringBuilder w_targets = new StringBuilder ();
- foreach (ProjectInfo info in websiteProjectInfos) {
- if (w_targets.Length > 0)
- w_targets.Append (";");
- w_targets.Append (GetTargetNameForProject (info.Name, buildTarget));
- }
-
- task = t.AddTask ("CallTarget");
- task.SetParameter ("Targets", w_targets.ToString ());
- task.SetParameter ("RunEachTargetSeparately", "true");
- }
- }
-
- // Sorts the ProjectInfo dependency graph, to obtain
- // a series of build levels with projects. Projects
- // in each level can be run parallel (no inter-dependency).
- static List<T>[] TopologicalSort<T> (IEnumerable<T> items) where T: ProjectInfo
- {
- IList<T> allItems;
- allItems = items as IList<T>;
- if (allItems == null)
- allItems = new List<T> (items);
-
- bool[] inserted = new bool[allItems.Count];
- bool[] triedToInsert = new bool[allItems.Count];
- int[] levels = new int [allItems.Count];
-
- int maxdepth = 0;
- for (int i = 0; i < allItems.Count; ++i) {
- int d = Insert<T> (i, allItems, levels, inserted, triedToInsert);
- if (d > maxdepth)
- maxdepth = d;
- }
-
- // Separate out the project infos by build level
- List<T>[] infosByLevel = new List<T>[maxdepth];
- for (int i = 0; i < levels.Length; i ++) {
- int level = levels [i] - 1;
- if (infosByLevel [level] == null)
- infosByLevel [level] = new List<T> ();
-
- infosByLevel [level].Add (allItems [i]);
- }
-
- return infosByLevel;
- }
-
- // returns level# for the project
- static int Insert<T> (int index, IList<T> allItems, int[] levels, bool[] inserted, bool[] triedToInsert)
- where T: ProjectInfo
- {
- if (inserted [index])
- return levels [index];
-
- if (triedToInsert[index])
- throw new InvalidOperationException (String.Format (
- "Cyclic dependency involving project {0} found in the project dependency graph",
- allItems [index].Name));
-
- triedToInsert[index] = true;
- ProjectInfo insertItem = allItems[index];
-
- int maxdepth = 0;
- foreach (ProjectInfo dependency in insertItem.Dependencies.Values) {
- for (int j = 0; j < allItems.Count; ++j) {
- ProjectInfo checkItem = allItems [j];
- if (dependency.FileName == checkItem.FileName) {
- int d = Insert (j, allItems, levels, inserted, triedToInsert);
- maxdepth = d > maxdepth ? d : maxdepth;
- break;
- }
- }
- }
- levels [index] = maxdepth + 1;
- inserted [index] = true;
-
- return levels [index];
- }
-
- public static IEnumerable<string> GetAllProjectFileNames (string solutionFile)
- {
- StreamReader reader = new StreamReader (solutionFile);
- string line = reader.ReadToEnd ();
- line = line.Replace ("\r\n", "\n");
- string soln_dir = Path.GetDirectoryName (solutionFile);
-
- Match m = projectRegex.Match (line);
- while (m.Success) {
- if (String.Compare (m.Groups [1].Value, solutionFolderGuid,
- StringComparison.InvariantCultureIgnoreCase) != 0)
- yield return Path.Combine (soln_dir, m.Groups [3].Value).Replace ("\\", "/");
-
- m = m.NextMatch ();
- }
- }
- }
-}