diff --git a/scripts/dotnet-cli-build/CompileTargets.cs b/scripts/dotnet-cli-build/CompileTargets.cs index 1fc300ce0..9cecf95de 100644 --- a/scripts/dotnet-cli-build/CompileTargets.cs +++ b/scripts/dotnet-cli-build/CompileTargets.cs @@ -293,41 +293,13 @@ namespace Microsoft.DotNet.Cli.Build } // Find crossgen - string arch = PlatformServices.Default.Runtime.RuntimeArchitecture; - string packageId; - if (CurrentPlatform.IsWindows) - { - packageId = $"runtime.win7-{arch}.Microsoft.NETCore.Runtime.CoreCLR"; - } - else if (CurrentPlatform.IsUbuntu) - { - packageId = "runtime.ubuntu.14.04-x64.Microsoft.NETCore.Runtime.CoreCLR"; - } - else if (CurrentPlatform.IsCentOS || CurrentPlatform.IsRHEL) - { - // CentOS runtime is in the runtime.rhel.7-x64... package. - packageId = "runtime.rhel.7-x64.Microsoft.NETCore.Runtime.CoreCLR"; - } - else if (CurrentPlatform.IsDebian) - { - packageId = "runtime.debian.8.2-x64.Microsoft.NETCore.Runtime.CoreCLR"; - } - else if (CurrentPlatform.IsOSX) - { - packageId = "runtime.osx.10.10-x64.Microsoft.NETCore.Runtime.CoreCLR"; - } - else + var crossGenExePath = Microsoft.DotNet.Cli.Build.Crossgen.GetCrossgenPathForVersion(CoreCLRVersion); + + if (string.IsNullOrEmpty(crossGenExePath)) { return c.Failed("Unsupported OS Platform"); } - var crossGenExePath = Path.Combine( - Dirs.NuGetPackages, - packageId, - CoreCLRVersion, - "tools", - $"crossgen{Constants.ExeSuffix}"); - // We have to copy crossgen next to mscorlib var crossgen = Path.Combine(outputDir, $"crossgen{Constants.ExeSuffix}"); File.Copy(crossGenExePath, crossgen, overwrite: true); diff --git a/scripts/dotnet-cli-build/SharedFrameworkTargets.cs b/scripts/dotnet-cli-build/SharedFrameworkTargets.cs index 760992734..e3b1d316f 100644 --- a/scripts/dotnet-cli-build/SharedFrameworkTargets.cs +++ b/scripts/dotnet-cli-build/SharedFrameworkTargets.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Text.RegularExpressions; +using System.Reflection.PortableExecutable; using System.Runtime.InteropServices; using Microsoft.DotNet.Cli.Build.Framework; using Microsoft.Extensions.PlatformAbstractions; @@ -51,6 +52,15 @@ namespace Microsoft.DotNet.Cli.Build // hostpolicy will be renamed to dotnet at some point and then this can be removed. File.Move(Path.Combine(SharedFrameworkNameAndVersionRoot, $"{Constants.DynamicLibPrefix}hostpolicy{Constants.DynamicLibSuffix}"), Path.Combine(SharedFrameworkNameAndVersionRoot, $"{Constants.DynamicLibPrefix}dotnethostimpl{Constants.DynamicLibSuffix}")); + if (File.Exists(Path.Combine(SharedFrameworkNameAndVersionRoot, "mscorlib.ni.dll"))) + { + // Publish already places the crossgen'd version of mscorlib into the output, so we can + // remove the IL version + File.Delete(Path.Combine(SharedFrameworkNameAndVersionRoot, "mscorlib.dll")); + + CrossGenAllManagedAssemblies(SharedFrameworkNameAndVersionRoot); + } + return c.Success(); } @@ -99,5 +109,47 @@ namespace Microsoft.DotNet.Cli.Build return null; } + + private static void CrossGenAllManagedAssemblies(string pathToAssemblies) + { + foreach (var file in Directory.GetFiles(pathToAssemblies)) + { + string fileName = Path.GetFileName(file); + + if (fileName == "mscorlib.dll" || fileName == "mscorlib.ni.dll" || !HasMetadata(file)) + { + continue; + } + + string tempPathName = Path.ChangeExtension(file, "readytorun"); + + // This is not always correct. The version of crossgen we need to pick up is whatever one was restored as part + // of the Microsoft.NETCore.Runtime.CoreCLR package that is part of the shared library. For now, the version hardcoded + // in CompileTargets and the one in the shared library project.json match and are updated in lock step, but long term + // we need to be able to look at the project.lock.json file and figure out what version of Microsoft.NETCore.Runtime.CoreCLR + // was used, and then select that version. + ExecSilent(Crossgen.GetCrossgenPathForVersion(CompileTargets.CoreCLRVersion), + "-readytorun", "-in", file, "-out", tempPathName, "-platform_assemblies_paths", pathToAssemblies); + + File.Delete(file); + File.Move(tempPathName, file); + } + } + + private static bool HasMetadata(string pathToFile) + { + try + { + using (var inStream = File.OpenRead(pathToFile)) + { + using (var peReader = new PEReader(inStream)) + { + return peReader.HasMetadata; + } + } + } catch (BadImageFormatException) { } + + return false; + } } -} \ No newline at end of file +} diff --git a/scripts/dotnet-cli-build/Utils/Crossgen.cs b/scripts/dotnet-cli-build/Utils/Crossgen.cs new file mode 100644 index 000000000..37cf836aa --- /dev/null +++ b/scripts/dotnet-cli-build/Utils/Crossgen.cs @@ -0,0 +1,50 @@ +using System.IO; +using System.Linq; +using System; +using System.Runtime.InteropServices; +using Microsoft.DotNet.Cli.Build.Framework; +using Microsoft.Extensions.PlatformAbstractions; + +namespace Microsoft.DotNet.Cli.Build +{ + internal static class Crossgen + { + public static string GetCrossgenPathForVersion(string coreClrVersion) + { + string arch = PlatformServices.Default.Runtime.RuntimeArchitecture; + string packageId; + if (CurrentPlatform.IsWindows) + { + packageId = $"runtime.win7-{arch}.Microsoft.NETCore.Runtime.CoreCLR"; + } + else if (CurrentPlatform.IsUbuntu) + { + packageId = "runtime.ubuntu.14.04-x64.Microsoft.NETCore.Runtime.CoreCLR"; + } + else if (CurrentPlatform.IsCentOS || CurrentPlatform.IsRHEL) + { + // CentOS runtime is in the runtime.rhel.7-x64... package. + packageId = "runtime.rhel.7-x64.Microsoft.NETCore.Runtime.CoreCLR"; + } + else if (CurrentPlatform.IsOSX) + { + packageId = "runtime.osx.10.10-x64.Microsoft.NETCore.Runtime.CoreCLR"; + } + else if (CurrentPlatform.IsDebian) + { + packageId = "runtime.debian.8.2-x64.Microsoft.NETCore.Runtime.CoreCLR"; + } + else + { + return null; + } + + return Path.Combine( + Dirs.NuGetPackages, + packageId, + coreClrVersion, + "tools", + $"crossgen{Constants.ExeSuffix}"); + } + } +} diff --git a/scripts/dotnet-cli-build/project.json b/scripts/dotnet-cli-build/project.json index 2be69c156..f66171d24 100755 --- a/scripts/dotnet-cli-build/project.json +++ b/scripts/dotnet-cli-build/project.json @@ -11,7 +11,8 @@ "System.Security.Cryptography.Algorithms": "4.0.0-rc2-23901", "Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-16537", "Microsoft.DotNet.Cli.Build.Framework": "1.0.0-*", - "WindowsAzure.Storage" : "6.2.2-preview" + "WindowsAzure.Storage" : "6.2.2-preview", + "System.Reflection.Metadata" : "1.2.0" }, "frameworks": { diff --git a/src/sharedframework/framework/project.json b/src/sharedframework/framework/project.json index 5d904b02f..48e835c95 100644 --- a/src/sharedframework/framework/project.json +++ b/src/sharedframework/framework/project.json @@ -5,7 +5,7 @@ }, "dependencies": { - "NETStandard.Library": "1.0.0-rc2-23811" + "NETStandard.Library": "1.0.0-rc2-23901" }, "frameworks": { diff --git a/src/sharedframework/host/project.json b/src/sharedframework/host/project.json index 30251684c..80a3611f2 100644 --- a/src/sharedframework/host/project.json +++ b/src/sharedframework/host/project.json @@ -2,7 +2,7 @@ "version": "1.0.0-*", "dependencies": { - "NETStandard.Library": "1.0.0-rc2-23811" + "NETStandard.Library": "1.0.0-rc2-23901" }, "frameworks": {