[xbuild] Use the env var $MSBuildExtensionsPath before trying other paths.
[mono.git] / mcs / class / Microsoft.Build.Engine / Microsoft.Build.BuildEngine / Import.cs
index ecb45ae5a6870a360194eb9b7949a1147fb790ba..9088babcfecf8444dc178ef46234374432af271f 100644 (file)
@@ -32,6 +32,7 @@ using System.IO;
 using System.Xml;
 
 using Microsoft.Build.Framework;
+using Mono.XBuild.Utilities;
 
 namespace Microsoft.Build.BuildEngine {
        public class Import {
@@ -42,6 +43,7 @@ namespace Microsoft.Build.BuildEngine {
 
                static string DotConfigExtensionsPath = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData),
                                                                Path.Combine ("xbuild", "tasks"));
+               const string MacOSXExternalXBuildDir = "/Library/Frameworks/Mono.framework/External/xbuild";
        
                internal Import (XmlElement importElement, Project project, ImportedProject originalProject)
                {
@@ -56,10 +58,13 @@ namespace Microsoft.Build.BuildEngine {
 
                        if (ProjectPath == String.Empty)
                                throw new InvalidProjectFileException ("The required attribute \"Project\" is missing from element <Import>.");
-                       evaluatedProjectPath = EvaluateProjectPath (ProjectPath);
-                       evaluatedProjectPath = GetFullPath ();
-                       if (EvaluatedProjectPath == String.Empty)
-                               throw new InvalidProjectFileException ("The required attribute \"Project\" is missing from element <Import>.");
+
+                       if (ConditionParser.ParseAndEvaluate (Condition, project)) {
+                               evaluatedProjectPath = EvaluateProjectPath (ProjectPath);
+                               evaluatedProjectPath = GetFullPath ();
+                               if (EvaluatedProjectPath == String.Empty)
+                                       throw new InvalidProjectFileException ("The required attribute \"Project\" is missing from element <Import>.");
+                       }
                }
 
                // FIXME: condition
@@ -87,42 +92,62 @@ namespace Microsoft.Build.BuildEngine {
 
                string EvaluateProjectPath (string file)
                {
-                       if (file.IndexOf ("$(MSBuildExtensionsPath)") >= 0) {
-                               // This is a *HACK* to support multiple paths for
-                               // MSBuildExtensionsPath property. Normally it would
-                               // get resolved to a single value, but here we special
-                               // case it and try ~/.config/xbuild/tasks and any
-                               // paths specified in the env var $MSBuildExtensionsPath .
-                               //
-                               // The property itself will resolve to the default
-                               // location though, so you get in any other part of the
-                               // project.
-
-                               string envvar = Environment.GetEnvironmentVariable ("MSBuildExtensionsPath");
-                               envvar = (envvar ?? String.Empty) + ":" + DotConfigExtensionsPath;
-
-                               string [] paths = envvar.Split (new char [] {':'}, StringSplitOptions.RemoveEmptyEntries);
-                               foreach (string path in paths) {
-                                       if (!Directory.Exists (path)) {
-                                               project.ParentEngine.LogMessage (MessageImportance.Low, "Extension path '{0}' not found, ignoring.", path);
-                                               continue;
-                                       }
-
-                                       string pfile = Path.GetFullPath (file.Replace ("\\", "/").Replace (
-                                                               "$(MSBuildExtensionsPath)", path + Path.DirectorySeparatorChar));
-
-                                       var evaluated_path = EvaluatePath (pfile);
-                                       if (File.Exists (evaluated_path)) {
-                                               project.ParentEngine.LogMessage (MessageImportance.Low,
-                                                       "{0}: Importing project {1} from extension path {2}", project.FullFileName, evaluated_path, path);
-                                               return pfile;
-                                       }
+                       string ret;
+                       if (EvaluateAsMSBuildExtensionsPath (file, "MSBuildExtensionsPath", out ret) ||
+                               EvaluateAsMSBuildExtensionsPath (file, "MSBuildExtensionsPath32", out ret) ||
+                               EvaluateAsMSBuildExtensionsPath (file, "MSBuildExtensionsPath64", out ret))
+                               return ret;
+
+                       return EvaluatePath (file);
+               }
+
+               bool EvaluateAsMSBuildExtensionsPath (string file, string property_name, out string epath)
+               {
+                       epath = null;
+                       string property_ref = String.Format ("$({0})", property_name);
+                       if (file.IndexOf (property_ref) < 0)
+                               return false;
+
+                       // This is a *HACK* to support multiple paths for
+                       // MSBuildExtensionsPath property. Normally it would
+                       // get resolved to a single value, but here we special
+                       // case it and try ~/.config/xbuild/tasks and any
+                       // paths specified in the env var $MSBuildExtensionsPath .
+                       //
+                       // The property itself will resolve to the default
+                       // location though, so you get in any other part of the
+                       // project.
+
+                       string envvar = Environment.GetEnvironmentVariable (property_name);
+                       envvar = String.Join (":", new string [] {
+                                               (envvar ?? String.Empty),
+                                               // For mac osx, look in the 'External' dir on macosx,
+                                               // see bug #663180
+                                               MSBuildUtils.RunningOnMac ? MacOSXExternalXBuildDir : String.Empty,
+                                               DotConfigExtensionsPath});
+
+                       string [] paths = envvar.Split (new char [] {':'}, StringSplitOptions.RemoveEmptyEntries);
+                       foreach (string path in paths) {
+                               if (!Directory.Exists (path)) {
+                                       project.ParentEngine.LogMessage (MessageImportance.Low, "Extension path '{0}' not found, ignoring.", path);
+                                       continue;
+                               }
+
+                               string pfile = Path.GetFullPath (file.Replace ("\\", "/").Replace (
+                                                       property_ref, path + Path.DirectorySeparatorChar));
+
+                               var evaluated_path = EvaluatePath (pfile);
+                               if (File.Exists (evaluated_path)) {
                                        project.ParentEngine.LogMessage (MessageImportance.Low,
-                                                       "{0}: Couldn't find project {1} for extension path {2}", project.FullFileName, evaluated_path, path);
+                                               "{0}: Importing project {1} from extension path {2}", project.FullFileName, evaluated_path, path);
+                                       epath = pfile;
+                                       return true;
                                }
+                               project.ParentEngine.LogMessage (MessageImportance.Low,
+                                               "{0}: Couldn't find project {1} for extension path {2}", project.FullFileName, evaluated_path, path);
                        }
 
-                       return EvaluatePath (file);
+                       return false;
                }
 
                string EvaluatePath (string path)
@@ -149,7 +174,7 @@ namespace Microsoft.Build.BuildEngine {
                                        file = Path.Combine (dir, EvaluatedProjectPath);
                        }
                        
-                       return Utilities.FromMSBuildPath (file);
+                       return MSBuildUtils.FromMSBuildPath (file);
                }
                
                public string Condition {