From ae49148a92c358676190772803fe0ed532814ce3 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Wed, 1 Nov 2023 10:37:12 +0100 Subject: [PATCH] implement full .NET 9 support (#2456) --- NuGet.Config | 1 + .../Jobs/RuntimeMoniker.cs | 20 +++++++++++++++++++ .../DotTraceDiagnoser.cs | 4 ++++ .../ConsoleArguments/ConfigParser.cs | 10 ++++++++++ .../Environments/Runtimes/CoreRuntime.cs | 4 +++- .../Environments/Runtimes/MonoRuntime.cs | 1 + .../Environments/Runtimes/NativeAotRuntime.cs | 6 ++++++ .../Extensions/RuntimeMonikerExtensions.cs | 8 ++++++++ .../Toolchains/CsProj/CsProjCoreToolchain.cs | 1 + .../DotNetCli/NetCoreAppSettings.cs | 1 + .../Toolchains/Mono/MonoToolchain.cs | 1 + .../NativeAot/NativeAotToolchain.cs | 8 ++++++++ .../Toolchains/ToolchainExtensions.cs | 10 ++++++++++ .../ConfigParserTests.cs | 1 + 14 files changed, 75 insertions(+), 1 deletion(-) diff --git a/NuGet.Config b/NuGet.Config index 2b16f5257e..855812b5a5 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -12,5 +12,6 @@ + diff --git a/src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs b/src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs index b0c34b4197..4fc2db7388 100644 --- a/src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs +++ b/src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs @@ -105,6 +105,11 @@ public enum RuntimeMoniker /// Net80, + /// + /// .NET 9.0 + /// + Net90, + /// /// NativeAOT compiled as net6.0 /// @@ -120,6 +125,11 @@ public enum RuntimeMoniker /// NativeAot80, + /// + /// NativeAOT compiled as net9.0 + /// + NativeAot90, + /// /// WebAssembly with default .Net version /// @@ -170,6 +180,11 @@ public enum RuntimeMoniker /// MonoAOTLLVMNet80, + /// + /// Mono with the Ahead of Time LLVM Compiler backend and net9.0 + /// + MonoAOTLLVMNet90, + /// /// .NET 6 using MonoVM (not CLR which is the default) /// @@ -184,5 +199,10 @@ public enum RuntimeMoniker /// .NET 8 using MonoVM (not CLR which is the default) /// Mono80, + + /// + /// .NET 9 using MonoVM (not CLR which is the default) + /// + Mono90, } } diff --git a/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs b/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs index 71eddec8d6..fe9e77005a 100644 --- a/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs +++ b/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs @@ -97,12 +97,14 @@ internal static bool IsSupported(RuntimeMoniker runtimeMoniker) case RuntimeMoniker.Net60: case RuntimeMoniker.Net70: case RuntimeMoniker.Net80: + case RuntimeMoniker.Net90: return true; case RuntimeMoniker.NotRecognized: case RuntimeMoniker.Mono: case RuntimeMoniker.NativeAot60: case RuntimeMoniker.NativeAot70: case RuntimeMoniker.NativeAot80: + case RuntimeMoniker.NativeAot90: case RuntimeMoniker.Wasm: case RuntimeMoniker.WasmNet50: case RuntimeMoniker.WasmNet60: @@ -113,9 +115,11 @@ internal static bool IsSupported(RuntimeMoniker runtimeMoniker) case RuntimeMoniker.MonoAOTLLVMNet60: case RuntimeMoniker.MonoAOTLLVMNet70: case RuntimeMoniker.MonoAOTLLVMNet80: + case RuntimeMoniker.MonoAOTLLVMNet90: case RuntimeMoniker.Mono60: case RuntimeMoniker.Mono70: case RuntimeMoniker.Mono80: + case RuntimeMoniker.Mono90: #pragma warning disable CS0618 // Type or member is obsolete case RuntimeMoniker.NetCoreApp50: #pragma warning restore CS0618 // Type or member is obsolete diff --git a/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs b/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs index 65f0e89fb4..0a125900f4 100644 --- a/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs +++ b/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs @@ -532,6 +532,7 @@ private static Job CreateJobForGivenRuntime(Job baseJob, string runtimeId, Comma case RuntimeMoniker.Net60: case RuntimeMoniker.Net70: case RuntimeMoniker.Net80: + case RuntimeMoniker.Net90: return baseJob .WithRuntime(runtimeMoniker.GetRuntime()) .WithToolchain(CsProjCoreToolchain.From(new NetCoreAppSettings(runtimeId, null, runtimeId, options.CliPath?.FullName, options.RestorePath?.FullName))); @@ -548,6 +549,9 @@ private static Job CreateJobForGivenRuntime(Job baseJob, string runtimeId, Comma case RuntimeMoniker.NativeAot80: return CreateAotJob(baseJob, options, runtimeMoniker, "", "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json"); + case RuntimeMoniker.NativeAot90: + return CreateAotJob(baseJob, options, runtimeMoniker, "", "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v3/index.json"); + case RuntimeMoniker.Wasm: return MakeWasmJob(baseJob, options, RuntimeInformation.IsNetCore ? CoreRuntime.GetCurrentVersion().MsBuildMoniker : "net5.0", runtimeMoniker); @@ -578,6 +582,9 @@ private static Job CreateJobForGivenRuntime(Job baseJob, string runtimeId, Comma case RuntimeMoniker.MonoAOTLLVMNet80: return MakeMonoAOTLLVMJob(baseJob, options, "net8.0"); + case RuntimeMoniker.MonoAOTLLVMNet90: + return MakeMonoAOTLLVMJob(baseJob, options, "net9.0"); + case RuntimeMoniker.Mono60: return MakeMonoJob(baseJob, options, MonoRuntime.Mono60); @@ -587,6 +594,9 @@ private static Job CreateJobForGivenRuntime(Job baseJob, string runtimeId, Comma case RuntimeMoniker.Mono80: return MakeMonoJob(baseJob, options, MonoRuntime.Mono80); + case RuntimeMoniker.Mono90: + return MakeMonoJob(baseJob, options, MonoRuntime.Mono90); + default: throw new NotSupportedException($"Runtime {runtimeId} is not supported"); } diff --git a/src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs b/src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs index 1f91648f90..d86e4b0f40 100644 --- a/src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs +++ b/src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs @@ -20,8 +20,9 @@ public class CoreRuntime : Runtime public static readonly CoreRuntime Core60 = new (RuntimeMoniker.Net60, "net6.0", ".NET 6.0"); public static readonly CoreRuntime Core70 = new (RuntimeMoniker.Net70, "net7.0", ".NET 7.0"); public static readonly CoreRuntime Core80 = new (RuntimeMoniker.Net80, "net8.0", ".NET 8.0"); + public static readonly CoreRuntime Core90 = new (RuntimeMoniker.Net90, "net9.0", ".NET 9.0"); - public static CoreRuntime Latest => Core80; // when dotnet/runtime branches for 9.0, this will need to get updated + public static CoreRuntime Latest => Core90; // when dotnet/runtime branches for 10.0, this will need to get updated private CoreRuntime(RuntimeMoniker runtimeMoniker, string msBuildMoniker, string displayName) : base(runtimeMoniker, msBuildMoniker, displayName) @@ -72,6 +73,7 @@ internal static CoreRuntime FromVersion(Version version) case Version v when v.Major == 6 && v.Minor == 0: return GetPlatformSpecific(Core60); case Version v when v.Major == 7 && v.Minor == 0: return GetPlatformSpecific(Core70); case Version v when v.Major == 8 && v.Minor == 0: return GetPlatformSpecific(Core80); + case Version v when v.Major == 9 && v.Minor == 0: return GetPlatformSpecific(Core90); default: return CreateForNewVersion($"net{version.Major}.{version.Minor}", $".NET {version.Major}.{version.Minor}"); } diff --git a/src/BenchmarkDotNet/Environments/Runtimes/MonoRuntime.cs b/src/BenchmarkDotNet/Environments/Runtimes/MonoRuntime.cs index 597e18b90c..5862d1390c 100644 --- a/src/BenchmarkDotNet/Environments/Runtimes/MonoRuntime.cs +++ b/src/BenchmarkDotNet/Environments/Runtimes/MonoRuntime.cs @@ -9,6 +9,7 @@ public class MonoRuntime : Runtime, IEquatable public static readonly MonoRuntime Mono60 = new ("Mono with .NET 6.0", RuntimeMoniker.Mono60, "net6.0", isDotNetBuiltIn: true); public static readonly MonoRuntime Mono70 = new ("Mono with .NET 7.0", RuntimeMoniker.Mono70, "net7.0", isDotNetBuiltIn: true); public static readonly MonoRuntime Mono80 = new ("Mono with .NET 8.0", RuntimeMoniker.Mono80, "net8.0", isDotNetBuiltIn: true); + public static readonly MonoRuntime Mono90 = new ("Mono with .NET 9.0", RuntimeMoniker.Mono90, "net9.0", isDotNetBuiltIn: true); public string CustomPath { get; } diff --git a/src/BenchmarkDotNet/Environments/Runtimes/NativeAotRuntime.cs b/src/BenchmarkDotNet/Environments/Runtimes/NativeAotRuntime.cs index 063210b37c..f1f49c5dca 100644 --- a/src/BenchmarkDotNet/Environments/Runtimes/NativeAotRuntime.cs +++ b/src/BenchmarkDotNet/Environments/Runtimes/NativeAotRuntime.cs @@ -18,6 +18,10 @@ public class NativeAotRuntime : Runtime /// NativeAOT compiled as net8.0 /// public static readonly NativeAotRuntime Net80 = new NativeAotRuntime(RuntimeMoniker.NativeAot80, "net8.0", "NativeAOT 8.0"); + /// + /// NativeAOT compiled as net9.0 + /// + public static readonly NativeAotRuntime Net90 = new NativeAotRuntime(RuntimeMoniker.NativeAot90, "net9.0", "NativeAOT 9.0"); public override bool IsAOT => true; @@ -42,6 +46,8 @@ public static NativeAotRuntime GetCurrentVersion() { case Version v when v.Major == 6 && v.Minor == 0: return Net60; case Version v when v.Major == 7 && v.Minor == 0: return Net70; + case Version v when v.Major == 8 && v.Minor == 0: return Net80; + case Version v when v.Major == 9 && v.Minor == 0: return Net90; default: return new NativeAotRuntime(RuntimeMoniker.NotRecognized, $"net{version.Major}.{version.Minor}", $"NativeAOT {version.Major}.{version.Minor}"); } diff --git a/src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs b/src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs index 60fa23df3e..5ba51eebdd 100644 --- a/src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs +++ b/src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs @@ -45,6 +45,8 @@ internal static Runtime GetRuntime(this RuntimeMoniker runtimeMoniker) return CoreRuntime.Core70; case RuntimeMoniker.Net80: return CoreRuntime.Core80; + case RuntimeMoniker.Net90: + return CoreRuntime.Core90; case RuntimeMoniker.Mono: return MonoRuntime.Default; case RuntimeMoniker.NativeAot60: @@ -53,10 +55,16 @@ internal static Runtime GetRuntime(this RuntimeMoniker runtimeMoniker) return NativeAotRuntime.Net70; case RuntimeMoniker.NativeAot80: return NativeAotRuntime.Net80; + case RuntimeMoniker.NativeAot90: + return NativeAotRuntime.Net90; case RuntimeMoniker.Mono60: return MonoRuntime.Mono60; case RuntimeMoniker.Mono70: return MonoRuntime.Mono70; + case RuntimeMoniker.Mono80: + return MonoRuntime.Mono80; + case RuntimeMoniker.Mono90: + return MonoRuntime.Mono90; default: throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, "Runtime Moniker not supported"); } diff --git a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs index 63ec4573b0..98bcd2ae8b 100644 --- a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs +++ b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs @@ -24,6 +24,7 @@ public class CsProjCoreToolchain : Toolchain, IEquatable [PublicAPI] public static readonly IToolchain NetCoreApp60 = From(NetCoreAppSettings.NetCoreApp60); [PublicAPI] public static readonly IToolchain NetCoreApp70 = From(NetCoreAppSettings.NetCoreApp70); [PublicAPI] public static readonly IToolchain NetCoreApp80 = From(NetCoreAppSettings.NetCoreApp80); + [PublicAPI] public static readonly IToolchain NetCoreApp90 = From(NetCoreAppSettings.NetCoreApp90); internal CsProjCoreToolchain(string name, IGenerator generator, IBuilder builder, IExecutor executor, string customDotNetCliPath) : base(name, generator, builder, executor) diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs index 26b76af0a6..664d1333f1 100644 --- a/src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs +++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs @@ -18,6 +18,7 @@ public class NetCoreAppSettings [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp60 = new ("net6.0", null, ".NET 6.0"); [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp70 = new ("net7.0", null, ".NET 7.0"); [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp80 = new ("net8.0", null, ".NET 8.0"); + [PublicAPI] public static readonly NetCoreAppSettings NetCoreApp90 = new ("net9.0", null, ".NET 9.0"); /// /// diff --git a/src/BenchmarkDotNet/Toolchains/Mono/MonoToolchain.cs b/src/BenchmarkDotNet/Toolchains/Mono/MonoToolchain.cs index ba2ae2ac96..56f2ebaa56 100644 --- a/src/BenchmarkDotNet/Toolchains/Mono/MonoToolchain.cs +++ b/src/BenchmarkDotNet/Toolchains/Mono/MonoToolchain.cs @@ -11,6 +11,7 @@ public class MonoToolchain : CsProjCoreToolchain, IEquatable [PublicAPI] public static readonly IToolchain Mono60 = From(new NetCoreAppSettings("net6.0", null, "mono60")); [PublicAPI] public static readonly IToolchain Mono70 = From(new NetCoreAppSettings("net7.0", null, "mono70")); [PublicAPI] public static readonly IToolchain Mono80 = From(new NetCoreAppSettings("net8.0", null, "mono80")); + [PublicAPI] public static readonly IToolchain Mono90 = From(new NetCoreAppSettings("net9.0", null, "mono90")); private MonoToolchain(string name, IGenerator generator, IBuilder builder, IExecutor executor, string customDotNetCliPath) : base(name, generator, builder, executor, customDotNetCliPath) diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchain.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchain.cs index 0beeff9627..4703c4b657 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchain.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/NativeAotToolchain.cs @@ -29,6 +29,14 @@ public class NativeAotToolchain : Toolchain .TargetFrameworkMoniker("net8.0") .ToToolchain(); + /// + /// compiled as net9.0, targets latest NativeAOT build from the .NET 9 feed: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v3/index.json + /// + public static readonly IToolchain Net90 = CreateBuilder() + .UseNuGet("", "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet9/nuget/v3/index.json") + .TargetFrameworkMoniker("net9.0") + .ToToolchain(); + internal NativeAotToolchain(string displayName, string ilCompilerVersion, string runtimeFrameworkVersion, string targetFrameworkMoniker, string runtimeIdentifier, diff --git a/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs b/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs index 918477f3b6..837c757cd7 100644 --- a/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs +++ b/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs @@ -66,6 +66,7 @@ internal static IToolchain GetToolchain(this Runtime runtime, Descriptor? descri RuntimeMoniker.Mono60 => GetToolchain(RuntimeMoniker.Net60), RuntimeMoniker.Mono70 => GetToolchain(RuntimeMoniker.Net70), RuntimeMoniker.Mono80 => GetToolchain(RuntimeMoniker.Net80), + RuntimeMoniker.Mono90 => GetToolchain(RuntimeMoniker.Net90), _ => CsProjCoreToolchain.From(new NetCoreAppSettings(mono.MsBuildMoniker, null, mono.Name)) }; } @@ -152,6 +153,9 @@ private static IToolchain GetToolchain(RuntimeMoniker runtimeMoniker) case RuntimeMoniker.Net80: return CsProjCoreToolchain.NetCoreApp80; + case RuntimeMoniker.Net90: + return CsProjCoreToolchain.NetCoreApp90; + case RuntimeMoniker.NativeAot60: return NativeAotToolchain.Net60; @@ -161,6 +165,9 @@ private static IToolchain GetToolchain(RuntimeMoniker runtimeMoniker) case RuntimeMoniker.NativeAot80: return NativeAotToolchain.Net80; + case RuntimeMoniker.NativeAot90: + return NativeAotToolchain.Net90; + case RuntimeMoniker.Mono60: return MonoToolchain.Mono60; @@ -170,6 +177,9 @@ private static IToolchain GetToolchain(RuntimeMoniker runtimeMoniker) case RuntimeMoniker.Mono80: return MonoToolchain.Mono80; + case RuntimeMoniker.Mono90: + return MonoToolchain.Mono90; + default: throw new ArgumentOutOfRangeException(nameof(runtimeMoniker), runtimeMoniker, "RuntimeMoniker not supported"); } diff --git a/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs b/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs index 538bad8a91..ec9b85021f 100644 --- a/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs +++ b/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs @@ -386,6 +386,7 @@ public void NetFrameworkMonikerParsedCorrectly(string tfm) [InlineData("net60")] [InlineData("net70")] [InlineData("net80")] + [InlineData("net90")] public void NetMonikersAreRecognizedAsNetCoreMonikers(string tfm) { var config = ConfigParser.Parse(new[] { "-r", tfm }, new OutputLogger(Output)).config;