public override bool Execute() { var log = new MSBuildLog(Log); var forcedPackageRanks = new PackageRank(ForcedPackages); var preferredPackageRanks = new PackageRank(PreferredPackages); // resolve conflicts at compile time var referenceItems = GetConflictTaskItems(References, ConflictItemType.Reference).ToArray(); var compileConflictScope = new ConflictResolver(forcedPackageRanks, preferredPackageRanks, log); compileConflictScope.ResolveConflicts(referenceItems, ci => ItemUtilities.GetReferenceFileName(ci.OriginalItem), HandleCompileConflict); // resolve conflicts that class in output var runtimeConflictScope = new ConflictResolver(forcedPackageRanks, preferredPackageRanks, log); runtimeConflictScope.ResolveConflicts(referenceItems, ci => ItemUtilities.GetReferenceTargetPath(ci.OriginalItem), HandleRuntimeConflict); var copyLocalItems = GetConflictTaskItems(ReferenceCopyLocalPaths, ConflictItemType.CopyLocal).ToArray(); runtimeConflictScope.ResolveConflicts(copyLocalItems, ci => ItemUtilities.GetTargetPath(ci.OriginalItem), HandleRuntimeConflict); var otherRuntimeItems = GetConflictTaskItems(OtherRuntimeItems, ConflictItemType.Runtime).ToArray(); runtimeConflictScope.ResolveConflicts(otherRuntimeItems, ci => ItemUtilities.GetTargetPath(ci.OriginalItem), HandleRuntimeConflict); // resolve conflicts with platform (eg: shared framework) items // we only commit the platform items since its not a conflict if other items share the same filename. var platformConflictScope = new ConflictResolver(forcedPackageRanks, preferredPackageRanks, log); var platformItems = PlatformManifests?.SelectMany(pm => PlatformManifestReader.LoadConflictItems(pm.ItemSpec, log)) ?? Enumerable.Empty <ConflictItem>(); platformConflictScope.ResolveConflicts(platformItems, pi => pi.FileName, pi => { }); platformConflictScope.ResolveConflicts(referenceItems.Where(ri => !referenceConflicts.Contains(ri.OriginalItem)), ri => ItemUtilities.GetReferenceTargetFileName(ri.OriginalItem), HandleRuntimeConflict, commitWinner: false); platformConflictScope.ResolveConflicts(copyLocalItems.Where(ci => !copyLocalConflicts.Contains(ci.OriginalItem)), ri => ri.FileName, HandleRuntimeConflict, commitWinner: false); platformConflictScope.ResolveConflicts(otherRuntimeItems, ri => ri.FileName, HandleRuntimeConflict, commitWinner: false); ReferencesWithoutConflicts = RemoveConflicts(References, referenceConflicts); ReferenceCopyLocalPathsWithoutConflicts = RemoveConflicts(ReferenceCopyLocalPaths, copyLocalConflicts); Conflicts = CreateConflictTaskItems(allConflicts); return(!Log.HasLoggedErrors); }
protected override void ExecuteCore() { var log = Log; var packageRanks = new PackageRank(PreferredPackages); var packageOverrides = new PackageOverrideResolver <ConflictItem>(PackageOverrides); // Treat assemblies from FrameworkList.xml as platform assemblies that also get considered at compile time IEnumerable <ConflictItem> compilePlatformItems = null; if (TargetFrameworkDirectories != null && TargetFrameworkDirectories.Any()) { var frameworkListReader = new FrameworkListReader(BuildEngine4); compilePlatformItems = TargetFrameworkDirectories.SelectMany(tfd => { return(frameworkListReader.GetConflictItems(Path.Combine(tfd.ItemSpec, "RedistList", "FrameworkList.xml"), log)); }).ToArray(); } // resolve conflicts at compile time var referenceItems = GetConflictTaskItems(References, ConflictItemType.Reference).ToArray(); using (var compileConflictScope = new ConflictResolver <ConflictItem>(packageRanks, packageOverrides, log)) { compileConflictScope.ResolveConflicts(referenceItems, ci => ItemUtilities.GetReferenceFileName(ci.OriginalItem), HandleCompileConflict); if (compilePlatformItems != null) { compileConflictScope.ResolveConflicts(compilePlatformItems, ci => ci.FileName, HandleCompileConflict); } } // Remove platform items which won a conflict with a reference but subsequently lost to something else compilePlatformWinners.ExceptWith(allConflicts); // resolve analyzer conflicts var analyzerItems = GetConflictTaskItems(Analyzers, ConflictItemType.Analyzer).ToArray(); using (var analyzerConflictScope = new ConflictResolver <ConflictItem>(packageRanks, packageOverrides, log)) { analyzerConflictScope.ResolveConflicts(analyzerItems, ci => ci.FileName, HandleAnalyzerConflict); } // resolve conflicts that clash in output IEnumerable <ConflictItem> copyLocalItems; IEnumerable <ConflictItem> otherRuntimeItems; using (var runtimeConflictScope = new ConflictResolver <ConflictItem>(packageRanks, packageOverrides, log)) { runtimeConflictScope.ResolveConflicts(referenceItems, ci => ItemUtilities.GetReferenceTargetPath(ci.OriginalItem), HandleRuntimeConflict); copyLocalItems = GetConflictTaskItems(ReferenceCopyLocalPaths, ConflictItemType.CopyLocal).ToArray(); runtimeConflictScope.ResolveConflicts(copyLocalItems, ci => ItemUtilities.GetTargetPath(ci.OriginalItem), HandleRuntimeConflict); otherRuntimeItems = GetConflictTaskItems(OtherRuntimeItems, ConflictItemType.Runtime).ToArray(); runtimeConflictScope.ResolveConflicts(otherRuntimeItems, ci => ItemUtilities.GetTargetPath(ci.OriginalItem), HandleRuntimeConflict); } // resolve conflicts with platform (eg: shared framework) items // we only commit the platform items since its not a conflict if other items share the same filename. using (var platformConflictScope = new ConflictResolver <ConflictItem>(packageRanks, packageOverrides, log)) { var platformItems = PlatformManifests?.SelectMany(pm => PlatformManifestReader.LoadConflictItems(pm.ItemSpec, log)) ?? Enumerable.Empty <ConflictItem>(); if (compilePlatformItems != null) { platformItems = platformItems.Concat(compilePlatformItems); } platformConflictScope.ResolveConflicts(platformItems, pi => pi.FileName, (winner, loser) => { }); platformConflictScope.ResolveConflicts(referenceItems.Where(ri => !referenceConflicts.Contains(ri.OriginalItem)), ri => ItemUtilities.GetReferenceTargetFileName(ri.OriginalItem), HandleRuntimeConflict, commitWinner: false); platformConflictScope.ResolveConflicts(copyLocalItems.Where(ci => !copyLocalConflicts.Contains(ci.OriginalItem)), ri => ri.FileName, HandleRuntimeConflict, commitWinner: false); platformConflictScope.ResolveConflicts(otherRuntimeItems, ri => ri.FileName, HandleRuntimeConflict, commitWinner: false); } ReferencesWithoutConflicts = RemoveConflicts(References, referenceConflicts); AnalyzersWithoutConflicts = RemoveConflicts(Analyzers, analyzerConflicts); ReferenceCopyLocalPathsWithoutConflicts = RemoveConflicts(ReferenceCopyLocalPaths, copyLocalConflicts); Conflicts = CreateConflictTaskItems(allConflicts); // This handles the issue described here: https://github.com/dotnet/sdk/issues/2221 // The issue is that before conflict resolution runs, references to assemblies in the framework // that also match an assembly coming from a NuGet package are either removed (in non-SDK targets // via the ResolveNuGetPackageAssets target in Microsoft.NuGet.targets) or transformed to refer // to the assembly coming from the NuGet package (for SDK projects in the ResolveLockFileReferences // task). // In either case, there ends up being no Reference item which will resolve to the DLL in // the reference assemblies. This is a problem if the platform item from the reference // assemblies wins a conflict in the compile scope, as the reference to the assembly from // the NuGet package will be removed, but there will be no reference to the Framework assembly // passed to the compiler. // So what we do is keep track of Platform items that win conflicts with Reference items in // the compile scope, and explicitly add references to them here. var referenceItemSpecs = new HashSet <string>(ReferencesWithoutConflicts?.Select(r => r.ItemSpec) ?? Enumerable.Empty <string>(), StringComparer.OrdinalIgnoreCase); ReferencesWithoutConflicts = SafeConcat(ReferencesWithoutConflicts, // The Reference item we create in this case should be without the .dll extension // (which is added in FrameworkListReader in order to make the framework items // correctly conflict with DLLs from NuGet packages) compilePlatformWinners.Select(c => Path.GetFileNameWithoutExtension(c.FileName)) // Don't add a reference if we already have one (especially in case the existing one has // metadata we want to keep, such as aliases) .Where(simplename => !referenceItemSpecs.Contains(simplename)) .Select(r => new TaskItem(r))); }
protected override void ExecuteCore() { var log = new MSBuildLog(Log); var packageRanks = new PackageRank(PreferredPackages); var packageOverrides = new PackageOverrideResolver <ConflictItem>(PackageOverrides); // Treat assemblies from FrameworkList.xml as platform assemblies that also get considered at compile time IEnumerable <ConflictItem> compilePlatformItems = null; if (TargetFrameworkDirectories != null && TargetFrameworkDirectories.Any()) { var frameworkListReader = new FrameworkListReader(BuildEngine4); compilePlatformItems = TargetFrameworkDirectories.SelectMany(tfd => { return(frameworkListReader.GetConflictItems(Path.Combine(tfd.ItemSpec, "RedistList", "FrameworkList.xml"), log)); }); } // resolve conflicts at compile time var referenceItems = GetConflictTaskItems(References, ConflictItemType.Reference).ToArray(); var compileConflictScope = new ConflictResolver <ConflictItem>(packageRanks, packageOverrides, log); compileConflictScope.ResolveConflicts(referenceItems, ci => ItemUtilities.GetReferenceFileName(ci.OriginalItem), HandleCompileConflict); if (compilePlatformItems != null) { compileConflictScope.ResolveConflicts(compilePlatformItems, ci => ci.FileName, HandleCompileConflict); } // resolve conflicts that class in output var runtimeConflictScope = new ConflictResolver <ConflictItem>(packageRanks, packageOverrides, log); runtimeConflictScope.ResolveConflicts(referenceItems, ci => ItemUtilities.GetReferenceTargetPath(ci.OriginalItem), HandleRuntimeConflict); var copyLocalItems = GetConflictTaskItems(ReferenceCopyLocalPaths, ConflictItemType.CopyLocal).ToArray(); runtimeConflictScope.ResolveConflicts(copyLocalItems, ci => ItemUtilities.GetTargetPath(ci.OriginalItem), HandleRuntimeConflict); var otherRuntimeItems = GetConflictTaskItems(OtherRuntimeItems, ConflictItemType.Runtime).ToArray(); runtimeConflictScope.ResolveConflicts(otherRuntimeItems, ci => ItemUtilities.GetTargetPath(ci.OriginalItem), HandleRuntimeConflict); // resolve conflicts with platform (eg: shared framework) items // we only commit the platform items since its not a conflict if other items share the same filename. var platformConflictScope = new ConflictResolver <ConflictItem>(packageRanks, packageOverrides, log); var platformItems = PlatformManifests?.SelectMany(pm => PlatformManifestReader.LoadConflictItems(pm.ItemSpec, log)) ?? Enumerable.Empty <ConflictItem>(); if (compilePlatformItems != null) { platformItems = platformItems.Concat(compilePlatformItems); } platformConflictScope.ResolveConflicts(platformItems, pi => pi.FileName, pi => { }); platformConflictScope.ResolveConflicts(referenceItems.Where(ri => !referenceConflicts.Contains(ri.OriginalItem)), ri => ItemUtilities.GetReferenceTargetFileName(ri.OriginalItem), HandleRuntimeConflict, commitWinner: false); platformConflictScope.ResolveConflicts(copyLocalItems.Where(ci => !copyLocalConflicts.Contains(ci.OriginalItem)), ri => ri.FileName, HandleRuntimeConflict, commitWinner: false); platformConflictScope.ResolveConflicts(otherRuntimeItems, ri => ri.FileName, HandleRuntimeConflict, commitWinner: false); ReferencesWithoutConflicts = RemoveConflicts(References, referenceConflicts); ReferenceCopyLocalPathsWithoutConflicts = RemoveConflicts(ReferenceCopyLocalPaths, copyLocalConflicts); Conflicts = CreateConflictTaskItems(allConflicts); }