diff --git a/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs b/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs index 60084f4d03d1b..6d278e4b9597a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs +++ b/src/coreclr/tools/aot/ILCompiler.Build.Tasks/ComputeManagedAssembliesToCompileToNative.cs @@ -5,6 +5,7 @@ using Microsoft.Build.Utilities; using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; @@ -99,16 +100,20 @@ public override bool Execute() var list = new List(); var assembliesToSkipPublish = new List(); var satelliteAssemblies = new List(); - var nativeAotFrameworkAssembliesToUse = new HashSet(); + var nativeAotFrameworkAssembliesToUse = new Dictionary(); foreach (ITaskItem taskItem in SdkAssemblies) { - nativeAotFrameworkAssembliesToUse.Add(Path.GetFileName(taskItem.ItemSpec)); + var fileName = Path.GetFileName(taskItem.ItemSpec); + if (!nativeAotFrameworkAssembliesToUse.ContainsKey(fileName)) + nativeAotFrameworkAssembliesToUse.Add(fileName, taskItem); } foreach (ITaskItem taskItem in FrameworkAssemblies) { - nativeAotFrameworkAssembliesToUse.Add(Path.GetFileName(taskItem.ItemSpec)); + var fileName = Path.GetFileName(taskItem.ItemSpec); + if (!nativeAotFrameworkAssembliesToUse.ContainsKey(fileName)) + nativeAotFrameworkAssembliesToUse.Add(fileName, taskItem); } foreach (ITaskItem taskItem in Assemblies) @@ -153,8 +158,21 @@ public override bool Execute() // Remove any assemblies whose implementation we want to come from NativeAOT's package. // Currently that's System.Private.* SDK assemblies and a bunch of framework assemblies. - if (nativeAotFrameworkAssembliesToUse.Contains(assemblyFileName)) + if (nativeAotFrameworkAssembliesToUse.TryGetValue(assemblyFileName, out ITaskItem frameworkItem)) { + if (GetFileVersion(itemSpec).CompareTo(GetFileVersion(frameworkItem.ItemSpec)) > 0) + { + if (assemblyFileName == "System.Private.CoreLib.dll") + { + Log.LogError($"Overriding System.Private.CoreLib.dll with a newer version is not supported. Attempted to use {itemSpec} instead of {frameworkItem.ItemSpec}."); + } + else + { + // Allow OOB references with higher version to take precedence over the framework assemblies. + list.Add(taskItem); + } + } + assembliesToSkipPublish.Add(taskItem); continue; } @@ -196,6 +214,12 @@ public override bool Execute() SatelliteAssemblies = satelliteAssemblies.ToArray(); return true; + + static Version GetFileVersion(string path) + { + var versionInfo = FileVersionInfo.GetVersionInfo(path); + return new Version(versionInfo.FileMajorPart, versionInfo.FileMinorPart, versionInfo.FileBuildPart, versionInfo.FilePrivatePart); + } } } }