X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FMicrosoft.Build.Tasks%2FMicrosoft.Build.Tasks%2FResolveAssemblyReference.cs;h=8ac434bb9a418471e8338bf738f43155fdc411fa;hb=c39718bbb394fe97281e6e64945b4572bef29121;hp=5b674be1db42167483b3cb081d36e5f82d7a0d02;hpb=d80e1ad5d0207b7677e795224b7a8e050988ddec;p=mono.git diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ResolveAssemblyReference.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ResolveAssemblyReference.cs index 5b674be1db4..8ac434bb9a4 100644 --- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ResolveAssemblyReference.cs +++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ResolveAssemblyReference.cs @@ -78,6 +78,7 @@ namespace Microsoft.Build.Tasks { List tempResolvedFiles; List primaryReferences; Dictionary alreadyScannedAssemblyNames; + Dictionary conflictWarningsCache; //FIXME: construct and use a graph of the dependencies, useful across projects @@ -98,6 +99,8 @@ namespace Microsoft.Build.Tasks { // nothing to resolve return true; + LogTaskParameters (); + assembly_resolver.Log = Log; tempResolvedFiles = new List (); tempCopyLocalFiles = new Dictionary (); @@ -107,9 +110,11 @@ namespace Microsoft.Build.Tasks { primaryReferences = new List (); assemblyNameToResolvedRef = new Dictionary (); + conflictWarningsCache = new Dictionary (); ResolveAssemblies (); ResolveAssemblyFiles (); + resolvedFiles = tempResolvedFiles.ToArray (); alreadyScannedAssemblyNames = new Dictionary (); @@ -121,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 (); @@ -135,6 +139,7 @@ namespace Microsoft.Build.Tasks { alreadyScannedAssemblyNames.Clear (); primaryReferences.Clear (); assemblyNameToResolvedRef.Clear (); + conflictWarningsCache.Clear (); dependency_search_paths = null; return true; @@ -151,11 +156,11 @@ namespace Microsoft.Build.Tasks { continue; } - Log.LogMessage (MessageImportance.Low, "Primary Reference {0}", item.ItemSpec); - ResolvedReference resolved_ref = ResolveReference (item, searchPaths); + LogWithPrecedingNewLine (MessageImportance.Low, "Primary Reference {0}", item.ItemSpec); + ResolvedReference resolved_ref = ResolveReference (item, searchPaths, true); if (resolved_ref == null) { - Log.LogWarning ("\tReference '{0}' not resolved", item.ItemSpec); - assembly_resolver.LogSearchLoggerMessages (); + Log.LogWarning ("Reference '{0}' not resolved", item.ItemSpec); + assembly_resolver.LogSearchLoggerMessages (MessageImportance.Normal); } else { Log.LogMessage (MessageImportance.Low, "\tReference {0} resolved to {1}. CopyLocal = {2}", @@ -166,8 +171,11 @@ 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)) { + !IsFromGacOrTargetFramework (resolved_ref) && + resolved_ref.FoundInSearchPath != SearchPath.PkgConfig) { primaryReferences.Add (new PrimaryReference ( resolved_ref.TaskItem, resolved_ref.TaskItem.GetMetadata ("CopyLocal"))); @@ -177,7 +185,7 @@ namespace Microsoft.Build.Tasks { } // Use @search_paths to resolve the reference - ResolvedReference ResolveReference (ITaskItem item, IEnumerable search_paths) + ResolvedReference ResolveReference (ITaskItem item, IEnumerable search_paths, bool set_copy_local) { ResolvedReference resolved = null; bool specific_version; @@ -205,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) { @@ -217,14 +225,15 @@ namespace Microsoft.Build.Tasks { } else { resolved = assembly_resolver.FindInDirectory ( item, spath, - allowedAssemblyExtensions ?? default_assembly_extensions); + allowedAssemblyExtensions ?? default_assembly_extensions, + specific_version); } if (resolved != null) break; } - if (resolved != null) + if (resolved != null && set_copy_local) SetCopyLocal (resolved.TaskItem, resolved.CopyLocal.ToString ()); return resolved; @@ -235,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; } @@ -260,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) { - Log.LogWarning ("\tReference '{0}' not resolved", item.ItemSpec); - assembly_resolver.LogSearchLoggerMessages (); + AssemblyName aname; + if (!assembly_resolver.TryGetAssemblyNameFromFile (item.ItemSpec, out aname)) { + Log.LogWarning ("Reference '{0}' not resolved", item.ItemSpec); + 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 (); @@ -289,7 +303,8 @@ namespace Microsoft.Build.Tasks { FindAndAddRelatedFiles (item.ItemSpec, copy_local); FindAndAddSatellites (item.ItemSpec, copy_local); - if (FindDependencies && !IsFromGacOrTargetFramework (rr)) + if (FindDependencies && !IsFromGacOrTargetFramework (rr) && + rr.FoundInSearchPath != SearchPath.PkgConfig) primaryReferences.Add (new PrimaryReference (item, copy_local)); } } @@ -317,10 +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)) + 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); } @@ -337,14 +354,13 @@ 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); item.SetMetadata ("SpecificVersion", "false"); - resolved_ref = ResolveReference (item, dependency_search_paths); + resolved_ref = ResolveReference (item, dependency_search_paths, false); - string copy_local = "false"; if (resolved_ref != null) { Log.LogMessage (MessageImportance.Low, "\tReference {0} resolved to {1}.", aname, resolved_ref.TaskItem.ItemSpec); @@ -353,13 +369,15 @@ 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 - resolved_ref.TaskItem.SetMetadata ("CopyLocal", parent_copy_local); + SetCopyLocal (resolved_ref.TaskItem, parent_copy_local); Log.LogMessage (MessageImportance.Low, "\tThis is CopyLocal {0} as parent item has this value", - copy_local); + parent_copy_local); if (TryAddNewReference (tempResolvedFiles, resolved_ref)) { FindAndAddRelatedFiles (resolved_ref.TaskItem.ItemSpec, parent_copy_local); @@ -368,15 +386,14 @@ namespace Microsoft.Build.Tasks { } else { //gac or tgtfmwk Log.LogMessage (MessageImportance.Low, - "\tThis is CopyLocal {0} as it is in the gac," + - "target framework directory or provided by a package.", - copy_local); + "\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 ("\tReference '{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; @@ -388,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); @@ -456,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; @@ -478,25 +495,28 @@ namespace Microsoft.Build.Tasks { assembly_resolver.LogSearchMessage ("Choosing '{0}' as it is a primary reference.", found_ref.AssemblyName.FullName); - Log.LogWarning ("Found a conflict between : '{0}' and '{1}'. Using '{0}' reference.", - 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; } - bool IsCopyLocal (ITaskItem item) + void LogWithPrecedingNewLine (MessageImportance importance, string format, params object [] args) { - return Boolean.Parse (item.GetMetadata ("CopyLocal")); + Log.LogMessage (importance, String.Empty); + Log.LogMessage (importance, format, args); } - bool IsFromTargetFramework (string filename) + // conflict b/w @main and @conflicting, picking @main + void LogConflictWarning (string main, string conflicting) { - foreach (string fpath in targetFrameworkDirectories) - if (filename.StartsWith (fpath)) - return true; - - return false; + string key = main + ":" + conflicting; + if (!conflictWarningsCache.ContainsKey (key)) { + Log.LogWarning ("Found a conflict between : '{0}' and '{1}'. Using '{0}' reference.", + main, conflicting); + conflictWarningsCache [key] = key; + } } bool IsFromGacOrTargetFramework (ResolvedReference rr) @@ -505,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; } @@ -626,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; } @@ -637,6 +687,7 @@ namespace Microsoft.Build.Tasks { set { targetProcessorArchitecture = value; } } + static Dictionary cultureNamesTable; static Dictionary CultureNamesTable { get {