List<ITaskItem> tempResolvedFiles;
List<PrimaryReference> primaryReferences;
Dictionary<string, string> alreadyScannedAssemblyNames;
+ Dictionary<string, string> conflictWarningsCache;
//FIXME: construct and use a graph of the dependencies, useful across projects
//FIXME: make this reusable
public override bool Execute ()
{
+ if (assemblies == null && assemblyFiles == null)
+ // nothing to resolve
+ return true;
+
assembly_resolver.Log = Log;
tempResolvedFiles = new List<ITaskItem> ();
tempCopyLocalFiles = new Dictionary<string, ITaskItem> ();
primaryReferences = new List<PrimaryReference> ();
assemblyNameToResolvedRef = new Dictionary<string, ResolvedReference> ();
+ conflictWarningsCache = new Dictionary<string, string> ();
- foreach (ITaskItem item in assemblies) {
- if (!String.IsNullOrEmpty (item.GetMetadata ("SubType"))) {
- Log.LogWarning ("Reference '{0}' has non-empty SubType. Ignoring.", item.ItemSpec);
- continue;
- }
-
- Log.LogMessage (MessageImportance.Low, "Primary Reference {0}", item.ItemSpec);
- ResolvedReference resolved_ref = ResolveReference (item, searchPaths);
- if (resolved_ref == null) {
- Log.LogWarning ("\tReference '{0}' not resolved", item.ItemSpec);
- Log.LogMessage ("{0}", assembly_resolver.SearchLogger.ToString ());
- } else {
- Log.LogMessage (MessageImportance.Low,
- "\tReference {0} resolved to {1}. CopyLocal = {2}",
- item.ItemSpec, resolved_ref.TaskItem,
- resolved_ref.TaskItem.GetMetadata ("CopyLocal"));
-
- Log.LogMessage (MessageImportance.Low,
- "\tReference found at search path {0}",
- resolved_ref.FoundInSearchPathAsString);
-
- if (TryAddNewReference (tempResolvedFiles, resolved_ref) &&
- !IsFromGacOrTargetFramework (resolved_ref)) {
- primaryReferences.Add (new PrimaryReference (
- resolved_ref.TaskItem,
- resolved_ref.TaskItem.GetMetadata ("CopyLocal")));
- }
- }
- }
-
+ ResolveAssemblies ();
ResolveAssemblyFiles ();
alreadyScannedAssemblyNames = new Dictionary<string, string> ();
alreadyScannedAssemblyNames.Clear ();
primaryReferences.Clear ();
assemblyNameToResolvedRef.Clear ();
+ conflictWarningsCache.Clear ();
dependency_search_paths = null;
return true;
}
+ void ResolveAssemblies ()
+ {
+ if (assemblies == null || assemblies.Length == 0)
+ return;
+
+ foreach (ITaskItem item in assemblies) {
+ if (!String.IsNullOrEmpty (item.GetMetadata ("SubType"))) {
+ Log.LogWarning ("Reference '{0}' has non-empty SubType. Ignoring.", item.ItemSpec);
+ continue;
+ }
+
+ 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 (MessageImportance.Normal);
+ } else {
+ if (Environment.GetEnvironmentVariable ("XBUILD_LOG_REFERENCE_RESOLVER") != null)
+ assembly_resolver.LogSearchLoggerMessages (MessageImportance.Low);
+
+ Log.LogMessage (MessageImportance.Low,
+ "\tReference {0} resolved to {1}. CopyLocal = {2}",
+ item.ItemSpec, resolved_ref.TaskItem,
+ resolved_ref.TaskItem.GetMetadata ("CopyLocal"));
+
+ Log.LogMessage (MessageImportance.Low,
+ "\tReference found at search path {0}",
+ resolved_ref.FoundInSearchPathAsString);
+
+ if (TryAddNewReference (tempResolvedFiles, resolved_ref) &&
+ !IsFromGacOrTargetFramework (resolved_ref) &&
+ resolved_ref.FoundInSearchPath != SearchPath.PkgConfig) {
+ primaryReferences.Add (new PrimaryReference (
+ resolved_ref.TaskItem,
+ resolved_ref.TaskItem.GetMetadata ("CopyLocal")));
+ }
+ }
+ }
+ }
+
// Use @search_paths to resolve the reference
- ResolvedReference ResolveReference (ITaskItem item, IEnumerable<string> search_paths)
+ ResolvedReference ResolveReference (ITaskItem item, IEnumerable<string> search_paths, bool set_copy_local)
{
ResolvedReference resolved = null;
bool specific_version;
return null;
foreach (string spath in search_paths) {
- assembly_resolver.SearchLogger.WriteLine ("For searchpath {0}", spath);
+ assembly_resolver.LogSearchMessage ("For searchpath {0}", spath);
if (String.Compare (spath, "{HintPathFromItem}") == 0) {
resolved = assembly_resolver.ResolveHintPathReference (item, specific_version);
} else if (String.Compare (spath, "{TargetFrameworkDirectory}") == 0) {
+ if (targetFrameworkDirectories == null)
+ continue;
foreach (string fpath in targetFrameworkDirectories) {
resolved = assembly_resolver.FindInTargetFramework (item,
fpath, specific_version);
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) {
- assembly_resolver.SearchLogger.WriteLine (
- "Warning: {CandidateAssemblyFiles} not supported currently");
+ assembly_resolver.LogSearchMessage (
+ "Warning: {{CandidateAssemblyFiles}} not supported currently");
} else if (String.Compare (spath, "{PkgConfig}") == 0) {
resolved = assembly_resolver.ResolvePkgConfigReference (item, specific_version);
} 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;
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;
}
//FIXME: Consider CandidateAssemblyFiles also here
void ResolveAssemblyFiles ()
{
+ if (assemblyFiles == null)
+ return;
+
foreach (ITaskItem item in assemblyFiles) {
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);
- Log.LogMessage ("{0}", assembly_resolver.SearchLogger.ToString ());
+ AssemblyName aname;
+ if (!assembly_resolver.TryGetAssemblyNameFromFile (item.ItemSpec, out aname)) {
+ Log.LogWarning ("Reference '{0}' not resolved", item.ItemSpec);
+ assembly_resolver.LogSearchLoggerMessages (MessageImportance.Normal);
continue;
}
+ if (Environment.GetEnvironmentVariable ("XBUILD_LOG_REFERENCE_RESOLVER") != null)
+ assembly_resolver.LogSearchLoggerMessages (MessageImportance.Low);
+
ResolvedReference rr = assembly_resolver.GetResolvedReference (item, item.ItemSpec, aname, true,
SearchPath.RawFileName);
copy_local = rr.CopyLocal.ToString ();
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));
}
}
ResolvedReference resolved_ref = ResolveDependencyByAssemblyName (
aname, asm.FullName, parent_copy_local);
- if (resolved_ref != null && !IsFromGacOrTargetFramework (resolved_ref))
+ if (resolved_ref != null && !IsFromGacOrTargetFramework (resolved_ref)
+ && resolved_ref.FoundInSearchPath != SearchPath.PkgConfig)
dependencies.Enqueue (resolved_ref.TaskItem.ItemSpec);
}
alreadyScannedAssemblyNames.Add (asm.FullName, String.Empty);
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) {
+ if (Environment.GetEnvironmentVariable ("XBUILD_LOG_REFERENCE_RESOLVER") != null)
+ assembly_resolver.LogSearchLoggerMessages (MessageImportance.Low);
+
Log.LogMessage (MessageImportance.Low, "\tReference {0} resolved to {1}.",
aname, resolved_ref.TaskItem.ItemSpec);
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);
} 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);
- Log.LogMessage ("{0}", assembly_resolver.SearchLogger.ToString ());
+ Log.LogWarning ("Reference '{0}' not resolved", aname);
+ assembly_resolver.LogSearchLoggerMessages (MessageImportance.Normal);
}
return resolved_ref;
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;
// we have a name match, but version mismatch!
- assembly_resolver.SearchLogger.WriteLine ("A conflict was detected between '{0}' and '{1}'",
+ assembly_resolver.LogSearchMessage ("A conflict was detected between '{0}' and '{1}'",
key_aname.FullName, found_ref.AssemblyName.FullName);
if (is_primary == found_ref.IsPrimary) {
- assembly_resolver.SearchLogger.WriteLine ("Unable to choose between the two. " +
+ assembly_resolver.LogSearchMessage ("Unable to choose between the two. " +
"Choosing '{0}' arbitrarily.", found_ref.AssemblyName.FullName);
return true;
}
// has to be a primary
// Prefer a primary reference over a dependency
- assembly_resolver.SearchLogger.WriteLine ("Choosing '{0}' as it is a primary reference.",
+ 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);
+ 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)
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; }
set { targetProcessorArchitecture = value; }
}
+
static Dictionary<string, string> cultureNamesTable;
static Dictionary<string, string> CultureNamesTable {
get {