Merge pull request #2971 from BrzVlad/feature-cross-binprot
[mono.git] / mcs / class / Microsoft.Build.Tasks / Microsoft.Build.Tasks / MSBuild.cs
index 340ed169c59881eca5eb227884f28af742b9b3de..dabc8c05c19fc971e0b803e2cc046acb95a2383f 100644 (file)
@@ -5,6 +5,7 @@
 //   Marek Sieradzki (marek.sieradzki@gmail.com)
 //
 // (C) 2005 Marek Sieradzki
+// Copyright 2011 Xamarin Inc
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-#if NET_2_0
 
 using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.IO;
+using Microsoft.Build.BuildEngine;
 using Microsoft.Build.Framework;
 using Microsoft.Build.Utilities;
 
@@ -44,6 +45,7 @@ namespace Microsoft.Build.Tasks {
                bool            rebaseOutputs;
                bool            runEachTargetSeparately;
                bool            stopOnFirstFailure;
+               bool            buildInParallel;
                ITaskItem []    targetOutputs;
                string []       targets;
        
@@ -53,27 +55,70 @@ namespace Microsoft.Build.Tasks {
 
                public override bool Execute ()
                {
+                       if (projects.Length == 0)
+                               return true;
+
                        string filename;
                        bool result = true;
+                       bool all_result = true;
                        stopOnFirstFailure = false;
                        List <ITaskItem > outputItems = new List <ITaskItem> ();
                        string currentDirectory = Environment.CurrentDirectory;
                        Hashtable outputs;
                
+                       var global_properties = SplitPropertiesToDictionary ();
+
+                       Log.LogMessage (MessageImportance.Low, "Global Properties:");
+                       if (global_properties != null)
+                               foreach (KeyValuePair<string, string> pair in global_properties)
+                                       Log.LogMessage (MessageImportance.Low, "\t{0} = {1}", pair.Key, pair.Value);
+
                        foreach (ITaskItem project in projects) {
                                filename = project.GetMetadata ("FullPath");
+                               if (!File.Exists (filename)) {
+                                       Log.LogError ("Could not find the project file '{0}'", filename);
+                                       if (stopOnFirstFailure)
+                                               break;
+
+                                       continue;
+                               }
 
                                Directory.SetCurrentDirectory (Path.GetDirectoryName (filename));
                                outputs = new Hashtable ();
 
-                               Dictionary<string, string> global_properties = SplitPropertiesToDictionary ();
-                               result = BuildEngine.BuildProjectFile (filename, targets, global_properties, outputs);
+                               try {
+                                       // Order of precedence:
+                                       // ToolsVersion property, %(Project.ToolsVersion)
+                                       string tv = ToolsVersion;
+                                       if (String.IsNullOrEmpty (tv))
+                                               // metadata on the Project item
+                                               tv = project.GetMetadata ("ToolsVersion");
+
+                                       if (!String.IsNullOrEmpty (tv) && Engine.GlobalEngine.Toolsets [tv] == null)
+                                               throw new UnknownToolsVersionException (tv);
+
+                                       result = BuildEngine2.BuildProjectFile (filename, targets, global_properties, outputs, tv);
+                               } catch (InvalidProjectFileException e) {
+                                       Log.LogError ("Error building project {0}: {1}", filename, e.Message);
+                                       result = false;
+                               }
+
+                               if (!result)
+                                       all_result = false;
 
                                if (result) {
                                        foreach (DictionaryEntry de in outputs) {
                                                ITaskItem [] array = (ITaskItem []) de.Value;
                                                foreach (ITaskItem item in array) {
-                                                       outputItems.Add (item);
+                                                       // DONT share items!
+                                                       ITaskItem new_item = new TaskItem (item);
+
+                                                       // copy the metadata from original @project to here
+                                                       // CopyMetadataTo does _not_ overwrite
+                                                       project.CopyMetadataTo (new_item);
+
+                                                       outputItems.Add (new_item);
+
                                                        //FIXME: Correctly rebase output paths to be relative to the
                                                        //       calling project
                                                        //if (rebaseOutputs)
@@ -81,17 +126,24 @@ namespace Microsoft.Build.Tasks {
                                                }
                                        }
                                } else {
-                                       Log.LogError ("Error while building {0}", filename);
                                        if (stopOnFirstFailure)
                                                break;
                                }
+
+                               Directory.SetCurrentDirectory (currentDirectory);
                        }
 
-                       if (result)
+                       if (all_result)
                                targetOutputs = outputItems.ToArray ();
 
                        Directory.SetCurrentDirectory (currentDirectory);
-                       return result;
+                       return all_result;
+               }
+
+               void ThrowIfInvalidToolsVersion (string toolsVersion)
+               {
+                       if (!String.IsNullOrEmpty (toolsVersion) && Engine.GlobalEngine.Toolsets [toolsVersion] == null)
+                               throw new UnknownToolsVersionException (toolsVersion);
                }
 
                [Required]
@@ -132,12 +184,21 @@ namespace Microsoft.Build.Tasks {
                        set { targets = value; }
                }
 
-               Dictionary<string, string> SplitPropertiesToDictionary ()
+               public bool BuildInParallel {
+                       get { return buildInParallel; }
+                       set { buildInParallel = value; }
+               }
+
+               public string ToolsVersion {
+                       get; set;
+               }
+
+               SortedDictionary<string, string> SplitPropertiesToDictionary ()
                {
                        if (properties == null)
                                return null;
 
-                       Dictionary<string, string> global_properties = new Dictionary<string, string> ();
+                       var global_properties = new SortedDictionary<string, string> ();
                        foreach (string kvpair in properties) {
                                if (String.IsNullOrEmpty (kvpair))
                                        continue;
@@ -157,4 +218,3 @@ namespace Microsoft.Build.Tasks {
        }
 }
 
-#endif