Merge pull request #820 from brendanzagaeski/master
[mono.git] / mcs / class / Microsoft.Build.Tasks / Microsoft.Build.Tasks / ResolveAssemblyReference.cs
index 4f7665d7dde7efb491f27fbb7f50d3dbca711f2b..8ac434bb9a418471e8338bf738f43155fdc411fa 100644 (file)
@@ -99,6 +99,8 @@ namespace Microsoft.Build.Tasks {
                                // nothing to resolve
                                return true;
 
+                       LogTaskParameters ();
+
                        assembly_resolver.Log = Log;
                        tempResolvedFiles = new List<ITaskItem> ();
                        tempCopyLocalFiles = new Dictionary<string, ITaskItem> ();
@@ -112,6 +114,7 @@ namespace Microsoft.Build.Tasks {
 
                        ResolveAssemblies ();
                        ResolveAssemblyFiles ();
+                       resolvedFiles = tempResolvedFiles.ToArray ();
 
                        alreadyScannedAssemblyNames = new Dictionary<string, string> ();
 
@@ -123,7 +126,6 @@ namespace Microsoft.Build.Tasks {
                        foreach (PrimaryReference pref in primaryReferences)
                                ResolveAssemblyFileDependencies (pref.TaskItem, pref.ParentCopyLocal);
 
-                       resolvedFiles = tempResolvedFiles.ToArray ();
                        copyLocalFiles = tempCopyLocalFiles.Values.ToArray ();
                        satelliteFiles = tempSatelliteFiles.Values.ToArray ();
                        relatedFiles = tempRelatedFiles.Values.ToArray ();
@@ -154,11 +156,11 @@ namespace Microsoft.Build.Tasks {
                                        continue;
                                }
 
-                               Log.LogMessage (MessageImportance.Low, "Primary Reference {0}", item.ItemSpec);
+                               LogWithPrecedingNewLine (MessageImportance.Low, "Primary Reference {0}", item.ItemSpec);
                                ResolvedReference resolved_ref = ResolveReference (item, searchPaths, true);
                                if (resolved_ref == null) {
                                        Log.LogWarning ("Reference '{0}' not resolved", item.ItemSpec);
-                                       assembly_resolver.LogSearchLoggerMessages ();
+                                       assembly_resolver.LogSearchLoggerMessages (MessageImportance.Normal);
                                } else {
                                        Log.LogMessage (MessageImportance.Low,
                                                        "\tReference {0} resolved to {1}. CopyLocal = {2}",
@@ -169,6 +171,8 @@ namespace Microsoft.Build.Tasks {
                                                        "\tReference found at search path {0}",
                                                        resolved_ref.FoundInSearchPathAsString);
 
+                                       assembly_resolver.LogSearchLoggerMessages (MessageImportance.Low);
+
                                        if (TryAddNewReference (tempResolvedFiles, resolved_ref) &&
                                                !IsFromGacOrTargetFramework (resolved_ref) &&
                                                resolved_ref.FoundInSearchPath != SearchPath.PkgConfig) {
@@ -209,8 +213,8 @@ namespace Microsoft.Build.Tasks {
                                        resolved = assembly_resolver.ResolveGacReference (item, specific_version);
                                } else if (String.Compare (spath, "{RawFileName}") == 0) {
                                        //FIXME: identify assembly names, as extract the name, and try with that?
-                                       AssemblyName aname = assembly_resolver.GetAssemblyNameFromFile (item.ItemSpec);
-                                       if (aname != null)
+                                       AssemblyName aname;
+                                       if (assembly_resolver.TryGetAssemblyNameFromFile (item.ItemSpec, out aname))
                                                resolved = assembly_resolver.GetResolvedReference (item, item.ItemSpec, aname, true,
                                                                SearchPath.RawFileName);
                                } else if (String.Compare (spath, "{CandidateAssemblyFiles}") == 0) {
@@ -221,7 +225,8 @@ namespace Microsoft.Build.Tasks {
                                } else {
                                        resolved = assembly_resolver.FindInDirectory (
                                                        item, spath,
-                                                       allowedAssemblyExtensions ?? default_assembly_extensions);
+                                                       allowedAssemblyExtensions ?? default_assembly_extensions,
+                                                       specific_version);
                                }
 
                                if (resolved != null)
@@ -239,10 +244,13 @@ namespace Microsoft.Build.Tasks {
                        specific_version = true;
                        string value = item.GetMetadata ("SpecificVersion");
                        if (String.IsNullOrEmpty (value)) {
-                               AssemblyName name = new AssemblyName (item.ItemSpec);
+                               //AssemblyName name = new AssemblyName (item.ItemSpec);
                                // If SpecificVersion is not specified, then
                                // it is true if the Include is a strong name else false
-                               specific_version = assembly_resolver.IsStrongNamed (name);
+                               //specific_version = assembly_resolver.IsStrongNamed (name);
+
+                               // msbuild seems to just look for a ',' in the name :/
+                               specific_version = item.ItemSpec.IndexOf (',') >= 0;
                                return true;
                        }
 
@@ -264,22 +272,24 @@ namespace Microsoft.Build.Tasks {
                                assembly_resolver.ResetSearchLogger ();
 
                                if (!File.Exists (item.ItemSpec)) {
-                                       Log.LogMessage (MessageImportance.Low,
+                                       LogWithPrecedingNewLine (MessageImportance.Low,
                                                        "Primary Reference from AssemblyFiles {0}, file not found. Ignoring",
                                                        item.ItemSpec);
                                        continue;
                                }
 
-                               Log.LogMessage (MessageImportance.Low, "Primary Reference from AssemblyFiles {0}", item.ItemSpec);
+                               LogWithPrecedingNewLine (MessageImportance.Low, "Primary Reference from AssemblyFiles {0}", item.ItemSpec);
                                string copy_local;
 
-                               AssemblyName aname = assembly_resolver.GetAssemblyNameFromFile (item.ItemSpec);
-                               if (aname == null) {
+                               AssemblyName aname;
+                               if (!assembly_resolver.TryGetAssemblyNameFromFile (item.ItemSpec, out aname)) {
                                        Log.LogWarning ("Reference '{0}' not resolved", item.ItemSpec);
-                                       assembly_resolver.LogSearchLoggerMessages ();
+                                       assembly_resolver.LogSearchLoggerMessages (MessageImportance.Normal);
                                        continue;
                                }
 
+                               assembly_resolver.LogSearchLoggerMessages (MessageImportance.Low);
+
                                ResolvedReference rr = assembly_resolver.GetResolvedReference (item, item.ItemSpec, aname, true,
                                                SearchPath.RawFileName);
                                copy_local = rr.CopyLocal.ToString ();
@@ -322,11 +332,12 @@ namespace Microsoft.Build.Tasks {
                                                continue;
 
                                        ResolvedReference resolved_ref = ResolveDependencyByAssemblyName (
-                                                       aname, asm.FullName, parent_copy_local);
+                                               aname, asm.FullName, parent_copy_local);
 
-                                       if (resolved_ref != null && !IsFromGacOrTargetFramework (resolved_ref)
-                                                       && resolved_ref.FoundInSearchPath != SearchPath.PkgConfig)
+                                       if (IncludeDependencies (resolved_ref, aname.FullName)) {
+                                               tempResolvedDepFiles[resolved_ref.AssemblyName.FullName] = resolved_ref.TaskItem;
                                                dependencies.Enqueue (resolved_ref.TaskItem.ItemSpec);
+                                       }
                                }
                                alreadyScannedAssemblyNames.Add (asm.FullName, String.Empty);
                        }
@@ -343,7 +354,7 @@ namespace Microsoft.Build.Tasks {
                        if (TryGetResolvedReferenceByAssemblyName (aname, false, out resolved_ref))
                                return resolved_ref;
 
-                       Log.LogMessage (MessageImportance.Low, "Dependency {0}", aname);
+                       LogWithPrecedingNewLine (MessageImportance.Low, "Dependency {0}", aname);
                        Log.LogMessage (MessageImportance.Low, "\tRequired by {0}", parent_asm_name);
 
                        ITaskItem item = new TaskItem (aname.FullName);
@@ -358,6 +369,8 @@ namespace Microsoft.Build.Tasks {
                                                "\tReference found at search path {0}",
                                                resolved_ref.FoundInSearchPathAsString);
 
+                               assembly_resolver.LogSearchLoggerMessages (MessageImportance.Low);
+
                                if (resolved_ref.FoundInSearchPath == SearchPath.Directory) {
                                        // override CopyLocal with parent's val
                                        SetCopyLocal (resolved_ref.TaskItem, parent_copy_local);
@@ -373,14 +386,14 @@ namespace Microsoft.Build.Tasks {
                                } else {
                                        //gac or tgtfmwk
                                        Log.LogMessage (MessageImportance.Low,
-                                                       "\tThis is CopyLocal false as it is in the gac," +
+                                                       "\tThis is CopyLocal false as it is in the GAC," +
                                                        "target framework directory or provided by a package.");
 
                                        TryAddNewReference (tempResolvedFiles, resolved_ref);
                                }
                        } else {
-                               Log.LogWarning ("Reference '{0}' not resolved", aname);
-                               assembly_resolver.LogSearchLoggerMessages ();
+                               Log.LogMessage (MessageImportance.Low, "Could not resolve the assembly \"{0}\".", aname);
+                               assembly_resolver.LogSearchLoggerMessages (MessageImportance.Low);
                        }
 
                        return resolved_ref;
@@ -392,7 +405,7 @@ namespace Microsoft.Build.Tasks {
                                return;
 
                        foreach (string ext in allowedRelatedFileExtensions) {
-                               string rfile = filename + ext;
+                               string rfile = Path.ChangeExtension (filename, ext);
                                if (File.Exists (rfile)) {
                                        ITaskItem item = new TaskItem (rfile);
                                        SetCopyLocal (item, parent_copy_local);
@@ -460,7 +473,7 @@ namespace Microsoft.Build.Tasks {
                                return false;
 
                        // match for full name
-                       if (AssemblyResolver.AssemblyNamesCompatible (key_aname, found_ref.AssemblyName, true))
+                       if (AssemblyResolver.AssemblyNamesCompatible (key_aname, found_ref.AssemblyName, true, false))
                                // exact match, so its already there, dont add anything
                                return true;
 
@@ -482,11 +495,19 @@ namespace Microsoft.Build.Tasks {
                        assembly_resolver.LogSearchMessage ("Choosing '{0}' as it is a primary reference.",
                                        found_ref.AssemblyName.FullName);
 
-                       LogConflictWarning (found_ref.AssemblyName.FullName, key_aname.FullName);
+                       // If we can successfully use the primary reference, don't log a warning. It's too
+                       // verbose.
+                       //LogConflictWarning (found_ref.AssemblyName.FullName, key_aname.FullName);
 
                        return true;
                }
 
+               void LogWithPrecedingNewLine (MessageImportance importance, string format, params object [] args)
+               {
+                       Log.LogMessage (importance, String.Empty);
+                       Log.LogMessage (importance, format, args);
+               }
+
                // conflict b/w @main and @conflicting, picking @main
                void LogConflictWarning (string main, string conflicting)
                {
@@ -504,6 +525,28 @@ namespace Microsoft.Build.Tasks {
                                rr.FoundInSearchPath == SearchPath.TargetFrameworkDirectory;
                }
 
+               bool IncludeDependencies (ResolvedReference rr, string aname)
+               {
+                       if (rr == null)
+                               return false;
+                       if (aname.Equals ("System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"))
+                               return true;
+                       return !IsFromGacOrTargetFramework (rr) && rr.FoundInSearchPath != SearchPath.PkgConfig;
+               }
+
+               void LogTaskParameters ()
+               {
+                       Log.LogMessage (MessageImportance.Low, "TargetFrameworkDirectories:");
+                       if (TargetFrameworkDirectories != null)
+                               foreach (string dir in TargetFrameworkDirectories)
+                                       Log.LogMessage (MessageImportance.Low, "\t{0}", dir);
+
+                       Log.LogMessage (MessageImportance.Low, "SearchPaths:");
+                       if (SearchPaths != null)
+                               foreach (string path in SearchPaths)
+                                       Log.LogMessage (MessageImportance.Low, "\t{0}", path);
+               }
+
                public bool AutoUnify {
                        get { return autoUnify; }
                        set { autoUnify = value; }
@@ -625,7 +668,15 @@ namespace Microsoft.Build.Tasks {
                public ITaskItem[] SuggestedRedirects {
                        get { return suggestedRedirects; }
                }
-               
+
+#if NET_4_0
+               public string TargetFrameworkMoniker { get; set; }
+
+               public string TargetFrameworkMonikerDisplayName { get; set; }
+#endif
+
+               public string TargetFrameworkVersion { get; set; }
+
                public string[] TargetFrameworkDirectories {
                        get { return targetFrameworkDirectories; }
                        set { targetFrameworkDirectories = value; }
@@ -636,6 +687,7 @@ namespace Microsoft.Build.Tasks {
                        set { targetProcessorArchitecture = value; }
                }
 
+
                 static Dictionary<string, string> cultureNamesTable;
                 static Dictionary<string, string> CultureNamesTable {
                         get {