diff --git a/.github/workflows/run-tests.yaml b/.github/workflows/run-tests.yaml
index f42f2596a5..2856388209 100644
--- a/.github/workflows/run-tests.yaml
+++ b/.github/workflows/run-tests.yaml
@@ -27,7 +27,7 @@ jobs:
run: ./build.cmd in-tests-core -e
# Upload Artifacts with Unique Name
- name: Upload test results
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: always()
with:
name: test-windows-core-trx-${{ github.run_id }}
diff --git a/README.md b/README.md
index 96feca8f9e..ed21385d53 100644
--- a/README.md
+++ b/README.md
@@ -112,7 +112,7 @@ The measured data can be exported to different formats (md, html, csv, xml, json

-*Supported runtimes:* .NET 5+, .NET Framework 4.6.1+, .NET Core 3.1+, Mono, NativeAOT
+*Supported runtimes:* .NET 5+, .NET Framework 4.6.1+, .NET Core 2.0+, Mono, NativeAOT
*Supported languages:* C#, F#, Visual Basic
*Supported OS:* Windows, Linux, macOS
*Supported architectures:* x86, x64, ARM, ARM64, Wasm and LoongArch64
@@ -135,8 +135,8 @@ If you want to compare benchmarks with each other,
mark one of the benchmarks as the [baseline](https://benchmarkdotnet.org/articles/features/baselines.html)
via `[Benchmark(Baseline = true)]`: BenchmarkDotNet will compare it with all of the other benchmarks.
If you want to compare performance in different environments, use [jobs](https://benchmarkdotnet.org/articles/configs/jobs.html).
-For example, you can run all the benchmarks on .NET Core 3.1 and Mono via
- `[SimpleJob(RuntimeMoniker.NetCoreApp31)]` and `[SimpleJob(RuntimeMoniker.Mono)]`.
+For example, you can run all the benchmarks on .NET 8.0 and Mono via
+ `[SimpleJob(RuntimeMoniker.Net80)]` and `[SimpleJob(RuntimeMoniker.Mono)]`.
If you don't like attributes, you can call most of the APIs via the fluent style and write code like this:
diff --git a/build/common.props b/build/common.props
index ccae1753c3..972f3ea9f6 100644
--- a/build/common.props
+++ b/build/common.props
@@ -23,7 +23,7 @@
trueannotations
-
+
true
diff --git a/docs/articles/faq.md b/docs/articles/faq.md
index 8f1cd41dc3..1fcfb13b1a 100644
--- a/docs/articles/faq.md
+++ b/docs/articles/faq.md
@@ -13,9 +13,9 @@ See also: [BenchmarkDotNet#237](https://github.com/dotnet/BenchmarkDotNet/issues
* **Q** Why can't I install BenchmarkDotNet in a new .NET Core Console App in Visual Studio 2017?
- **A** BenchmarkDotNet supports only netcoreapp3.1+.
+ **A** BenchmarkDotNet supports only netcoreapp2.0+.
Some old Visual Studio 2017 can create a new application which targets netcoreapp1.0.
-You should upgrade it up to 3.1.
+You should upgrade it up to 2.0.
If you want to target netcoreapp1.0 in your main assembly, it's recommended to create a separated project for benchmarks.
* **Q** I created a new .NET Core Console App in Visual Studio 2017. Now I want to run my code on CoreCLR, full .NET Framework, and Mono. How can I do it?
@@ -23,7 +23,7 @@ If you want to target netcoreapp1.0 in your main assembly, it's recommended to c
**A** Use the following lines in your `.csproj` file:
```xml
- netcoreapp3.1;net46
+ netcoreapp2.0;net46AnyCPU
```
@@ -33,7 +33,7 @@ If you want to target netcoreapp1.0 in your main assembly, it's recommended to c
[CoreJob, ClrJob, MonoJob]
```
-* **Q** My source code targets old versions of .NET Framework or .NET Core, but BenchmarkDotNet requires `net461` and `netcoreapp3.1`. How can I run benchmarks in this case?
+* **Q** My source code targets old versions of .NET Framework or .NET Core, but BenchmarkDotNet requires `net461` and `netcoreapp2.0`. How can I run benchmarks in this case?
**A** It's a good practice to introduce an additional console application (e.g. `MyAwesomeLibrary.Benchmarks`) which will depend on your code and BenchmarkDotNet.
Due to the fact that users usually run benchmarks in a develop environment and don't distribute benchmarks for users, it shouldn't be a problem.
diff --git a/docs/articles/guides/troubleshooting.md b/docs/articles/guides/troubleshooting.md
index 2574f3d1aa..1a998886cc 100644
--- a/docs/articles/guides/troubleshooting.md
+++ b/docs/articles/guides/troubleshooting.md
@@ -11,7 +11,7 @@ How do you know that BenchmarkDotNet has failed to build the project? BDN is goi
// ***** BenchmarkRunner: Start *****
// ***** Found 1 benchmark(s) in total *****
// ***** Building 1 exe(s) in Parallel: Start *****
-// start dotnet restore /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 /p:Deterministic=true /p:Optimize=true in C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\net8.0\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4
+// start dotnet restore /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 /p:Deterministic=true /p:Optimize=true in C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\netcoreapp2.1\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4
// command took 0.51s and exited with 1
// ***** Done, took 00:00:00 (0.66 sec) *****
// Found 1 benchmarks:
@@ -20,10 +20,10 @@ How do you know that BenchmarkDotNet has failed to build the project? BDN is goi
// Build Error: Standard output:
Standard error:
- C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\net8.0\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4\BenchmarkDotNet.Autogenerated.csproj(36,1): error MSB4025: The project file could not be loaded. Unexpected end of file while parsing Comment has occurred. Line 36, position 1.
+ C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\netcoreapp2.1\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4\BenchmarkDotNet.Autogenerated.csproj(36,1): error MSB4025: The project file could not be loaded. Unexpected end of file while parsing Comment has occurred. Line 36, position 1.
// BenchmarkDotNet has failed to build the auto-generated boilerplate code.
-// It can be found in C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\net8.0\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4
+// It can be found in C:\Projects\BenchmarkDotNet\samples\BenchmarkDotNet.Samples\bin\Release\netcoreapp2.1\c6045772-d3c7-4dbe-ab37-4aca6dcb6ec4
// Please follow the troubleshooting guide: https://benchmarkdotnet.org/articles/guides/troubleshooting.html
```
diff --git a/docs/articles/overview.md b/docs/articles/overview.md
index f6f502d004..e777049ee1 100644
--- a/docs/articles/overview.md
+++ b/docs/articles/overview.md
@@ -10,7 +10,7 @@ name: Overview
Create new console application and install the [BenchmarkDotNet](https://www.nuget.org/packages/BenchmarkDotNet/) NuGet package. We support:
* *Projects:* classic and modern with PackageReferences
-* *Runtimes:* Full .NET Framework (4.6+), .NET Core (3.1+), Mono, NativeAOT
+* *Runtimes:* Full .NET Framework (4.6+), .NET Core (2.0+), Mono, NativeAOT
* *OS:* Windows, Linux, MacOS
* *Languages:* C#, F#, VB
diff --git a/src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs b/src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs
index 4ad24192e2..16b242d2dc 100644
--- a/src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs
+++ b/src/BenchmarkDotNet.Annotations/Jobs/RuntimeMoniker.cs
@@ -57,27 +57,22 @@ public enum RuntimeMoniker
///
/// .NET Core 2.0
///
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
- // Assigning explicit values so we can check for them without the compiler erroring.
- NetCoreApp20 = 10,
+ NetCoreApp20,
///
/// .NET Core 2.1
///
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
- NetCoreApp21 = 11,
+ NetCoreApp21,
///
/// .NET Core 2.2
///
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
- NetCoreApp22 = 12,
+ NetCoreApp22,
///
/// .NET Core 3.0
///
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
- NetCoreApp30 = 13,
+ NetCoreApp30,
///
/// .NET Core 3.1
diff --git a/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs b/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs
index b7d23e9275..7616ca468c 100644
--- a/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs
+++ b/src/BenchmarkDotNet.Diagnostics.dotMemory/DotMemoryDiagnoser.cs
@@ -112,6 +112,11 @@ internal override bool IsSupported(RuntimeMoniker runtimeMoniker)
case RuntimeMoniker.NetCoreApp50:
#pragma warning restore CS0618 // Type or member is obsolete
return false;
+ case RuntimeMoniker.NetCoreApp20:
+ case RuntimeMoniker.NetCoreApp21:
+ case RuntimeMoniker.NetCoreApp22:
+ return OsDetector.IsWindows();
+ case RuntimeMoniker.NetCoreApp30:
case RuntimeMoniker.NetCoreApp31:
return OsDetector.IsWindows() || OsDetector.IsLinux();
default:
diff --git a/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs b/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs
index 0dded47443..8b5d3a858f 100644
--- a/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs
+++ b/src/BenchmarkDotNet.Diagnostics.dotTrace/DotTraceDiagnoser.cs
@@ -115,6 +115,11 @@ internal override bool IsSupported(RuntimeMoniker runtimeMoniker)
case RuntimeMoniker.NetCoreApp50:
#pragma warning restore CS0618 // Type or member is obsolete
return false;
+ case RuntimeMoniker.NetCoreApp20:
+ case RuntimeMoniker.NetCoreApp21:
+ case RuntimeMoniker.NetCoreApp22:
+ return OsDetector.IsWindows();
+ case RuntimeMoniker.NetCoreApp30:
case RuntimeMoniker.NetCoreApp31:
return OsDetector.IsWindows() || OsDetector.IsLinux();
default:
diff --git a/src/BenchmarkDotNet/BenchmarkDotNet.csproj b/src/BenchmarkDotNet/BenchmarkDotNet.csproj
index 739ecbd85d..26938fb36a 100644
--- a/src/BenchmarkDotNet/BenchmarkDotNet.csproj
+++ b/src/BenchmarkDotNet/BenchmarkDotNet.csproj
@@ -23,7 +23,6 @@
-
diff --git a/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs b/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs
index b59836e395..51e1667c60 100644
--- a/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs
+++ b/src/BenchmarkDotNet/ConsoleArguments/ConfigParser.cs
@@ -519,6 +519,10 @@ private static Job CreateJobForGivenRuntime(Job baseJob, string runtimeId, Comma
.WithRuntime(runtimeMoniker.GetRuntime())
.WithToolchain(CsProjClassicNetToolchain.From(runtimeId, options.RestorePath?.FullName, options.CliPath?.FullName));
+ case RuntimeMoniker.NetCoreApp20:
+ case RuntimeMoniker.NetCoreApp21:
+ case RuntimeMoniker.NetCoreApp22:
+ case RuntimeMoniker.NetCoreApp30:
case RuntimeMoniker.NetCoreApp31:
#pragma warning disable CS0618 // Type or member is obsolete
case RuntimeMoniker.NetCoreApp50:
diff --git a/src/BenchmarkDotNet/Diagnosers/EventPipeProfiler.cs b/src/BenchmarkDotNet/Diagnosers/EventPipeProfiler.cs
index 81f1abdf75..c1c76e8c9e 100644
--- a/src/BenchmarkDotNet/Diagnosers/EventPipeProfiler.cs
+++ b/src/BenchmarkDotNet/Diagnosers/EventPipeProfiler.cs
@@ -62,9 +62,9 @@ public IEnumerable Validate(ValidationParameters validationPara
{
var runtime = benchmark.Job.ResolveValue(EnvironmentMode.RuntimeCharacteristic, EnvironmentResolver.Instance);
- if (runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp31)
+ if (runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp30)
{
- yield return new ValidationError(true, $"{nameof(EventPipeProfiler)} supports only .NET Core 3.1+", benchmark);
+ yield return new ValidationError(true, $"{nameof(EventPipeProfiler)} supports only .NET Core 3.0+", benchmark);
}
}
}
diff --git a/src/BenchmarkDotNet/Diagnosers/ThreadingDiagnoser.cs b/src/BenchmarkDotNet/Diagnosers/ThreadingDiagnoser.cs
index 52059ca21c..36b2f942c3 100644
--- a/src/BenchmarkDotNet/Diagnosers/ThreadingDiagnoser.cs
+++ b/src/BenchmarkDotNet/Diagnosers/ThreadingDiagnoser.cs
@@ -45,9 +45,9 @@ public IEnumerable Validate(ValidationParameters validationPara
{
var runtime = benchmark.Job.ResolveValue(EnvironmentMode.RuntimeCharacteristic, EnvironmentResolver.Instance);
- if (runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp31)
+ if (runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp30)
{
- yield return new ValidationError(true, $"{nameof(ThreadingDiagnoser)} supports only .NET Core 3.1+", benchmark);
+ yield return new ValidationError(true, $"{nameof(ThreadingDiagnoser)} supports only .NET Core 3.0+", benchmark);
}
}
}
diff --git a/src/BenchmarkDotNet/Disassemblers/DisassemblyDiagnoser.cs b/src/BenchmarkDotNet/Disassemblers/DisassemblyDiagnoser.cs
index 1c98b0752c..7d0f95326c 100644
--- a/src/BenchmarkDotNet/Disassemblers/DisassemblyDiagnoser.cs
+++ b/src/BenchmarkDotNet/Disassemblers/DisassemblyDiagnoser.cs
@@ -117,6 +117,11 @@ public IEnumerable Validate(ValidationParameters validationPara
{
var runtime = benchmark.Job.ResolveValue(EnvironmentMode.RuntimeCharacteristic, EnvironmentResolver.Instance);
+ if (runtime.RuntimeMoniker < RuntimeMoniker.NetCoreApp30)
+ {
+ yield return new ValidationError(true, $"{nameof(DisassemblyDiagnoser)} supports only .NET Core 3.0+", benchmark);
+ }
+
if (ptrace_scope.Value == "2")
{
yield return new ValidationError(false, $"ptrace_scope is set to 2, {nameof(DisassemblyDiagnoser)} is going to work only if you run as sudo");
diff --git a/src/BenchmarkDotNet/Engines/GcStats.cs b/src/BenchmarkDotNet/Engines/GcStats.cs
index 9c4c639737..ca60b0deea 100644
--- a/src/BenchmarkDotNet/Engines/GcStats.cs
+++ b/src/BenchmarkDotNet/Engines/GcStats.cs
@@ -39,7 +39,7 @@ private GcStats(int gen0Collections, int gen1Collections, int gen2Collections, l
public long? GetBytesAllocatedPerOperation(BenchmarkCase benchmarkCase)
{
- bool excludeAllocationQuantumSideEffects = benchmarkCase.GetRuntime().RuntimeMoniker <= (RuntimeMoniker) 10; // the issue got fixed for .NET Core 2.0+ https://github.com/dotnet/coreclr/issues/10207
+ bool excludeAllocationQuantumSideEffects = benchmarkCase.GetRuntime().RuntimeMoniker <= RuntimeMoniker.NetCoreApp20; // the issue got fixed for .NET Core 2.0+ https://github.com/dotnet/coreclr/issues/10207
long? allocatedBytes = GetTotalAllocatedBytes(excludeAllocationQuantumSideEffects);
return allocatedBytes == null ? null
diff --git a/src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs b/src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs
index 66f918338c..53476adbc8 100644
--- a/src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs
+++ b/src/BenchmarkDotNet/Environments/Runtimes/CoreRuntime.cs
@@ -11,13 +11,9 @@ namespace BenchmarkDotNet.Environments
{
public class CoreRuntime : Runtime
{
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
public static readonly CoreRuntime Core20 = new (RuntimeMoniker.NetCoreApp20, "netcoreapp2.0", ".NET Core 2.0");
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
public static readonly CoreRuntime Core21 = new (RuntimeMoniker.NetCoreApp21, "netcoreapp2.1", ".NET Core 2.1");
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
public static readonly CoreRuntime Core22 = new (RuntimeMoniker.NetCoreApp22, "netcoreapp2.2", ".NET Core 2.2");
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
public static readonly CoreRuntime Core30 = new (RuntimeMoniker.NetCoreApp30, "netcoreapp3.0", ".NET Core 3.0");
public static readonly CoreRuntime Core31 = new (RuntimeMoniker.NetCoreApp31, "netcoreapp3.1", ".NET Core 3.1");
public static readonly CoreRuntime Core50 = new (RuntimeMoniker.Net50, "net5.0", ".NET 5.0");
@@ -69,6 +65,10 @@ internal static CoreRuntime FromVersion(Version version)
{
switch (version)
{
+ case Version v when v.Major == 2 && v.Minor == 0: return Core20;
+ case Version v when v.Major == 2 && v.Minor == 1: return Core21;
+ case Version v when v.Major == 2 && v.Minor == 2: return Core22;
+ case Version v when v.Major == 3 && v.Minor == 0: return Core30;
case Version v when v.Major == 3 && v.Minor == 1: return Core31;
case Version v when v.Major == 5 && v.Minor == 0: return GetPlatformSpecific(Core50);
case Version v when v.Major == 6 && v.Minor == 0: return GetPlatformSpecific(Core60);
@@ -77,9 +77,7 @@ internal static CoreRuntime FromVersion(Version version)
case Version v when v.Major == 9 && v.Minor == 0: return GetPlatformSpecific(Core90);
case Version v when v.Major == 10 && v.Minor == 0: return GetPlatformSpecific(Core10_0);
default:
- return version >= new Version(3, 1)
- ? CreateForNewVersion($"net{version.Major}.{version.Minor}", $".NET {version.Major}.{version.Minor}")
- : throw new PlatformNotSupportedException($"netcoreapp{version.Major}.{version.Minor} is no longer supported. Use a newer runtime version or use BenchmarkDotNet v0.14.X or older.");
+ return CreateForNewVersion($"net{version.Major}.{version.Minor}", $".NET {version.Major}.{version.Minor}");
}
}
diff --git a/src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs b/src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs
index ab905bd21e..94f82c8232 100644
--- a/src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs
+++ b/src/BenchmarkDotNet/Extensions/RuntimeMonikerExtensions.cs
@@ -24,6 +24,14 @@ internal static Runtime GetRuntime(this RuntimeMoniker runtimeMoniker)
return ClrRuntime.Net48;
case RuntimeMoniker.Net481:
return ClrRuntime.Net481;
+ case RuntimeMoniker.NetCoreApp20:
+ return CoreRuntime.Core20;
+ case RuntimeMoniker.NetCoreApp21:
+ return CoreRuntime.Core21;
+ case RuntimeMoniker.NetCoreApp22:
+ return CoreRuntime.Core22;
+ case RuntimeMoniker.NetCoreApp30:
+ return CoreRuntime.Core30;
case RuntimeMoniker.NetCoreApp31:
return CoreRuntime.Core31;
case RuntimeMoniker.Net50:
diff --git a/src/BenchmarkDotNet/Templates/CsProj.txt b/src/BenchmarkDotNet/Templates/CsProj.txt
index 5cd08250dc..c20e376e3c 100644
--- a/src/BenchmarkDotNet/Templates/CsProj.txt
+++ b/src/BenchmarkDotNet/Templates/CsProj.txt
@@ -26,6 +26,8 @@
truefalse
+
+ trueBenchmarkDotNet.Autogenerated.UniqueProgramName
diff --git a/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt b/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
index 1db40072d1..7be0730fd7 100644
--- a/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
+++ b/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
@@ -20,6 +20,8 @@
trueBenchmarkDotNet.Autogenerated.UniqueProgramNametrue
+
+ true
diff --git a/src/BenchmarkDotNet/Templates/WasmCsProj.txt b/src/BenchmarkDotNet/Templates/WasmCsProj.txt
index e45f5c3789..fffc648e0b 100644
--- a/src/BenchmarkDotNet/Templates/WasmCsProj.txt
+++ b/src/BenchmarkDotNet/Templates/WasmCsProj.txt
@@ -26,6 +26,8 @@
falsefalsefalse
+
+ trueBenchmarkDotNet.Autogenerated.UniqueProgramName
diff --git a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs
index 5e88641187..4aea1327f8 100644
--- a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs
+++ b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjCoreToolchain.cs
@@ -15,13 +15,9 @@ namespace BenchmarkDotNet.Toolchains.CsProj
[PublicAPI]
public class CsProjCoreToolchain : Toolchain, IEquatable
{
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
[PublicAPI] public static readonly IToolchain NetCoreApp20 = From(NetCoreAppSettings.NetCoreApp20);
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
[PublicAPI] public static readonly IToolchain NetCoreApp21 = From(NetCoreAppSettings.NetCoreApp21);
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
[PublicAPI] public static readonly IToolchain NetCoreApp22 = From(NetCoreAppSettings.NetCoreApp22);
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
[PublicAPI] public static readonly IToolchain NetCoreApp30 = From(NetCoreAppSettings.NetCoreApp30);
[PublicAPI] public static readonly IToolchain NetCoreApp31 = From(NetCoreAppSettings.NetCoreApp31);
[PublicAPI] public static readonly IToolchain NetCoreApp50 = From(NetCoreAppSettings.NetCoreApp50);
diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs
index 7427b167d1..028e4f2bd3 100644
--- a/src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs
+++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/NetCoreAppSettings.cs
@@ -1,6 +1,5 @@
using BenchmarkDotNet.Toolchains.MonoAotLLVM;
using JetBrains.Annotations;
-using System;
namespace BenchmarkDotNet.Toolchains.DotNetCli
{
@@ -10,13 +9,9 @@ namespace BenchmarkDotNet.Toolchains.DotNetCli
[PublicAPI]
public class NetCoreAppSettings
{
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp20 = new ("netcoreapp2.0", null, ".NET Core 2.0");
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp21 = new ("netcoreapp2.1", null, ".NET Core 2.1");
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp22 = new ("netcoreapp2.2", null, ".NET Core 2.2");
- [Obsolete("This runtime is no longer supported. Use a newer runtime or use BenchmarkDotNet v0.14.X or older.", true)]
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp30 = new ("netcoreapp3.0", null, ".NET Core 3.0");
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp31 = new ("netcoreapp3.1", null, ".NET Core 3.1");
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp50 = new ("net5.0", null, ".NET 5.0");
diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs
index 061b64a9a8..f1e32d6c6b 100644
--- a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs
+++ b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs
@@ -143,6 +143,7 @@ private string GenerateProjectForNuGetBuild(BuildPartition buildPartition, Artif
falsefalsefalse
+ true
{GetInstructionSetSettings(buildPartition)}
{GetRuntimeSettings(buildPartition.RepresentativeBenchmarkCase.Job.Environment.Gc, buildPartition.Resolver)}
diff --git a/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs b/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs
index ba8b3c6863..2beab5018c 100644
--- a/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs
+++ b/src/BenchmarkDotNet/Toolchains/ToolchainExtensions.cs
@@ -124,6 +124,18 @@ private static IToolchain GetToolchain(RuntimeMoniker runtimeMoniker)
case RuntimeMoniker.Net481:
return CsProjClassicNetToolchain.Net481;
+ case RuntimeMoniker.NetCoreApp20:
+ return CsProjCoreToolchain.NetCoreApp20;
+
+ case RuntimeMoniker.NetCoreApp21:
+ return CsProjCoreToolchain.NetCoreApp21;
+
+ case RuntimeMoniker.NetCoreApp22:
+ return CsProjCoreToolchain.NetCoreApp22;
+
+ case RuntimeMoniker.NetCoreApp30:
+ return CsProjCoreToolchain.NetCoreApp30;
+
case RuntimeMoniker.NetCoreApp31:
return CsProjCoreToolchain.NetCoreApp31;
#pragma warning disable CS0618 // Type or member is obsolete
diff --git a/src/BenchmarkDotNet/Validators/DotNetSdkVersionValidator.cs b/src/BenchmarkDotNet/Validators/DotNetSdkVersionValidator.cs
index 14965a436d..17331b49f8 100644
--- a/src/BenchmarkDotNet/Validators/DotNetSdkVersionValidator.cs
+++ b/src/BenchmarkDotNet/Validators/DotNetSdkVersionValidator.cs
@@ -210,6 +210,10 @@ private static Version GetSdkVersionFromMoniker(RuntimeMoniker runtimeMoniker)
RuntimeMoniker.Net472 => new Version(4, 7, 2),
RuntimeMoniker.Net48 => new Version(4, 8),
RuntimeMoniker.Net481 => new Version(4, 8, 1),
+ RuntimeMoniker.NetCoreApp20 => new Version(2, 0),
+ RuntimeMoniker.NetCoreApp21 => new Version(2, 1),
+ RuntimeMoniker.NetCoreApp22 => new Version(2, 2),
+ RuntimeMoniker.NetCoreApp30 => new Version(3, 0),
RuntimeMoniker.NetCoreApp31 => new Version(3, 1),
RuntimeMoniker.Net50 => new Version(5, 0),
RuntimeMoniker.Net60 => new Version(6, 0),
diff --git a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj
index 282009baad..12457479b4 100644
--- a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj
+++ b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks.csproj
@@ -2,8 +2,8 @@
BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks
-
- net462;net48;netcoreapp3.1;net8.0
+
+ net461;net48;netcoreapp2.0;net8.0$(NoWarn);NETSDK1138;NU1901;NU1902;NU1903;NU1904false
@@ -38,9 +38,10 @@
-
-
-
+
+
+
+
allruntime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs
index a73a47e7c2..b9cf360c8f 100644
--- a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs
+++ b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs
@@ -3,7 +3,6 @@
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Extensions;
using BenchmarkDotNet.Jobs;
-using BenchmarkDotNet.Portability;
using Xunit;
namespace BenchmarkDotNet.IntegrationTests.ManualRunning
@@ -13,13 +12,13 @@ public class MultipleFrameworksTest : BenchmarkTestExecutor
private const string TfmEnvVarName = "TfmEnvVarName";
[Theory]
- [InlineData(RuntimeMoniker.Net462)]
+ [InlineData(RuntimeMoniker.Net461)]
[InlineData(RuntimeMoniker.Net48)]
- [InlineData(RuntimeMoniker.NetCoreApp31)]
+ [InlineData(RuntimeMoniker.NetCoreApp20)]
[InlineData(RuntimeMoniker.Net80)]
public void EachFrameworkIsRebuilt(RuntimeMoniker runtime)
{
-#if NET462
+#if NET461
// We cannot detect what target framework version the host was compiled for on full Framework,
// which causes the RoslynToolchain to be used instead of CsProjClassicNetToolchain when the host is full Framework
// (because full Framework always uses the version that's installed on the machine, unlike Core),
@@ -40,12 +39,12 @@ public void EachFrameworkIsRebuilt(RuntimeMoniker runtime)
public class ValuePerTfm
{
private const RuntimeMoniker moniker =
-#if NET462
- RuntimeMoniker.Net462;
+#if NET461
+ RuntimeMoniker.Net461;
#elif NET48
RuntimeMoniker.Net48;
-#elif NETCOREAPP3_1
- RuntimeMoniker.NetCoreApp31;
+#elif NETCOREAPP2_0
+ RuntimeMoniker.NetCoreApp20;
#elif NET8_0
RuntimeMoniker.Net80;
#else
@@ -57,7 +56,7 @@ public void ThrowWhenWrong()
{
if (Environment.GetEnvironmentVariable(TfmEnvVarName) != moniker.ToString())
{
- throw new InvalidOperationException($"Has not been recompiled, the value was {Environment.GetEnvironmentVariable(TfmEnvVarName)}");
+ throw new InvalidOperationException($"Has not been recompiled, the value was {moniker}, expected {Environment.GetEnvironmentVariable(TfmEnvVarName)}");
}
}
}
diff --git a/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs b/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs
index 2a4373eef0..a14ea685cb 100644
--- a/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs
+++ b/tests/BenchmarkDotNet.Tests/ConfigParserTests.cs
@@ -271,10 +271,16 @@ public void IlCompilerPathParsedCorrectly()
}
[Theory]
+ [InlineData("netcoreapp2.0", true)]
+ [InlineData("netcoreapp2.1", true)]
+ [InlineData("netcoreapp2.2", true)]
+ [InlineData("netcoreapp3.0", true)]
[InlineData("netcoreapp3.1", true)]
[InlineData("net5.0", true)]
[InlineData("net6.0", true)]
+ [InlineData("net7.0", true)]
[InlineData("net8.0", true)]
+ [InlineData("net9.0", true)]
[InlineData("net462", false)]
[InlineData("net48", false)]
public void DotNetCliParsedCorrectly(string tfm, bool isCore)
@@ -421,15 +427,15 @@ public void PlatformSpecificMonikersAreSupported(string msBuildMoniker)
[Fact]
public void CanCompareFewDifferentRuntimes()
{
- var config = ConfigParser.Parse(["--runtimes", "net462", "MONO", "netcoreapp3.1", "nativeaot6.0", "nativeAOT7.0", "nativeAOT8.0"],
+ var config = ConfigParser.Parse(["--runtimes", "net462", "MONO", "netcoreapp2.0", "nativeaot6.0", "nativeAOT7.0", "nativeAOT8.0"],
new OutputLogger(Output)).config;
Assert.True(config.GetJobs().First().Meta.Baseline); // when the user provides multiple runtimes the first one should be marked as baseline
Assert.Single(config.GetJobs(), job => job.Environment.Runtime is ClrRuntime clrRuntime && clrRuntime.MsBuildMoniker == "net462");
Assert.Single(config.GetJobs(), job => job.Environment.Runtime is MonoRuntime);
Assert.Single(config.GetJobs(), job =>
- job.Environment.Runtime is CoreRuntime coreRuntime && coreRuntime.MsBuildMoniker == "netcoreapp3.1" &&
- coreRuntime.RuntimeMoniker == RuntimeMoniker.NetCoreApp31);
+ job.Environment.Runtime is CoreRuntime coreRuntime && coreRuntime.MsBuildMoniker == "netcoreapp2.0" &&
+ coreRuntime.RuntimeMoniker == RuntimeMoniker.NetCoreApp20);
Assert.Single(config.GetJobs(), job =>
job.Environment.Runtime is NativeAotRuntime nativeAot && nativeAot.MsBuildMoniker == "net6.0" &&
nativeAot.RuntimeMoniker == RuntimeMoniker.NativeAot60);
diff --git a/tests/BenchmarkDotNet.Tests/RuntimeVersionDetectionTests.cs b/tests/BenchmarkDotNet.Tests/RuntimeVersionDetectionTests.cs
index 876d0ae42e..f6286720fd 100644
--- a/tests/BenchmarkDotNet.Tests/RuntimeVersionDetectionTests.cs
+++ b/tests/BenchmarkDotNet.Tests/RuntimeVersionDetectionTests.cs
@@ -12,6 +12,10 @@ namespace BenchmarkDotNet.Tests
public class RuntimeVersionDetectionTests
{
[Theory]
+ [InlineData(".NETCoreApp,Version=v2.0", RuntimeMoniker.NetCoreApp20, "netcoreapp2.0")]
+ [InlineData(".NETCoreApp,Version=v2.1", RuntimeMoniker.NetCoreApp21, "netcoreapp2.1")]
+ [InlineData(".NETCoreApp,Version=v2.2", RuntimeMoniker.NetCoreApp22, "netcoreapp2.2")]
+ [InlineData(".NETCoreApp,Version=v3.0", RuntimeMoniker.NetCoreApp30, "netcoreapp3.0")]
[InlineData(".NETCoreApp,Version=v3.1", RuntimeMoniker.NetCoreApp31, "netcoreapp3.1")]
[InlineData(".NETCoreApp,Version=v5.0", RuntimeMoniker.Net50, "net5.0")]
[InlineData(".NETCoreApp,Version=v6.0", RuntimeMoniker.Net60, "net6.0")]
@@ -40,6 +44,9 @@ public void TryGetVersionFromFrameworkNameHandlesInvalidInput(string? frameworkN
}
[Theory]
+ [InlineData(RuntimeMoniker.NetCoreApp21, "netcoreapp2.1", "Microsoft .NET Framework", "4.6.27817.01 @BuiltBy: dlab14-DDVSOWINAGE101 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/coreclr/tree/6f78fbb3f964b4f407a2efb713a186384a167e5c")]
+ [InlineData(RuntimeMoniker.NetCoreApp22, "netcoreapp2.2", "Microsoft .NET Framework", "4.6.27817.03 @BuiltBy: dlab14-DDVSOWINAGE101 @Branch: release/2.2 @SrcCode: https://github.com/dotnet/coreclr/tree/ce1d090d33b400a25620c0145046471495067cc7")]
+ [InlineData(RuntimeMoniker.NetCoreApp30, "netcoreapp3.0", "Microsoft .NET Core", "3.0.0-preview8-28379-12")]
[InlineData(RuntimeMoniker.NetCoreApp31, "netcoreapp3.1", "Microsoft .NET Core", "3.1.0-something")]
[InlineData(RuntimeMoniker.Net50, "net5.0", "Microsoft .NET Core", "5.0.0-alpha1.19415.3")]
[InlineData(RuntimeMoniker.NotRecognized, "net123.0", "Microsoft .NET Core", "123.0.0-future")]
@@ -67,6 +74,10 @@ public static IEnumerable