diff --git a/src/BenchmarkDotNet/Templates/CsProj.txt b/src/BenchmarkDotNet/Templates/CsProj.txt
index 610b204fca..9afef8cf5e 100644
--- a/src/BenchmarkDotNet/Templates/CsProj.txt
+++ b/src/BenchmarkDotNet/Templates/CsProj.txt
@@ -8,20 +8,12 @@
$PROGRAMNAME$
Exe
False
-
- false
+ false
false
- false
-
false
- true
-
- true
false
-
- true
BenchmarkDotNet.Autogenerated.UniqueProgramName
diff --git a/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt b/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
index 248d17329a..f005cd82b4 100644
--- a/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
+++ b/src/BenchmarkDotNet/Templates/MonoAOTLLVMCsProj.txt
@@ -9,6 +9,9 @@
Exe
+ False
+ false
+ false
$TFM$
$RUNTIMEPACK$
$RUNTIMEIDENTIFIER$
@@ -16,11 +19,10 @@
false
$PROGRAMNAME$
false
+ false
true
BenchmarkDotNet.Autogenerated.UniqueProgramName
true
-
- true
diff --git a/src/BenchmarkDotNet/Templates/R2RCsProj.txt b/src/BenchmarkDotNet/Templates/R2RCsProj.txt
index ae9fd774d3..e881418b1b 100644
--- a/src/BenchmarkDotNet/Templates/R2RCsProj.txt
+++ b/src/BenchmarkDotNet/Templates/R2RCsProj.txt
@@ -9,20 +9,12 @@
$PROGRAMNAME$
Exe
False
-
- false
+ false
false
- false
-
false
- true
-
- true
false
-
- true
BenchmarkDotNet.Autogenerated.UniqueProgramName
false
diff --git a/src/BenchmarkDotNet/Templates/WasmCsProj.txt b/src/BenchmarkDotNet/Templates/WasmCsProj.txt
index 8542f55eb9..68915fe4f6 100644
--- a/src/BenchmarkDotNet/Templates/WasmCsProj.txt
+++ b/src/BenchmarkDotNet/Templates/WasmCsProj.txt
@@ -10,6 +10,9 @@
$CORECLR_OVERRIDES$
Exe
+ False
+ false
+ false
Release
false
$TFM$
@@ -23,8 +26,6 @@ $CORECLR_OVERRIDES$
false
false
false
-
- true
BenchmarkDotNet.Autogenerated.UniqueProgramName
diff --git a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs
index a368959b4f..08956ba6ea 100644
--- a/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs
+++ b/src/BenchmarkDotNet/Toolchains/CsProj/CsProjGenerator.cs
@@ -33,9 +33,18 @@ public class CsProjGenerator : DotNetCliGenerator, IEquatable
"UserSecretsId",
"EnablePreviewFeatures",
"RuntimeHostConfigurationOption",
- "WarningsAsErrors",
"Features",
- "GarbageCollectionAdaptationMode" // TODO: Remove this setting after https://github.com/dotnet/runtime/pull/131069 issue is resolved, and backported to .NET 10.
+
+ "WarningsAsErrors",
+ "WarningsNotAsErrors",
+ "WarningLevel",
+ "NoWarn",
+ "MSBuildWarningsAsErrors",
+ "MSBuildWarningsNotAsErrors",
+ "MSBuildWarningsAsMessages",
+ "SuppressTfmSupportBuildWarnings",
+
+ "GarbageCollectionAdaptationMode", // TODO: Remove this setting after https://github.com/dotnet/runtime/pull/131069 issue is resolved, and backported to .NET 10.
}.ToImmutableArray();
public string RuntimeFrameworkVersion { get; }
diff --git a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommandExecutor.cs b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommandExecutor.cs
index a37af02634..4bced8ca12 100644
--- a/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommandExecutor.cs
+++ b/src/BenchmarkDotNet/Toolchains/DotNetCli/DotNetCliCommandExecutor.cs
@@ -7,6 +7,7 @@
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.Results;
using JetBrains.Annotations;
+using System.Collections.Immutable;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
@@ -56,9 +57,38 @@ public static async Task ExecuteAsync(DotNetCliCommand p
parameters.Logger.WriteLineInfo($"// command took {stopwatch.Elapsed.TotalSeconds.ToInvariantString("0.##")} sec and exited with {process.ExitCode}");
- return process.ExitCode <= 0
- ? DotNetCliCommandResult.Success(stopwatch.Elapsed, outputReader.GetOutputText())
- : DotNetCliCommandResult.Failure(stopwatch.Elapsed, outputReader.GetOutputText(), outputReader.GetErrorText());
+ if (process.ExitCode != 0)
+ {
+ return DotNetCliCommandResult.Failure(stopwatch.Elapsed, outputReader.GetOutputText(), outputReader.GetErrorText());
+ }
+
+ // A successful build's output is otherwise discarded (see DotNetCliCommandResult.ToBuildResult), so
+ // build/restore warnings (e.g. NU1701, NU1702) would be invisible unless LogBuildOutput is set. When the
+ // full output isn't already being streamed, surface just the warning lines so they aren't silently lost.
+ if (!parameters.LogOutput)
+ LogBuildWarnings(parameters.Logger, outputReader.GetOutputLines());
+
+ return DotNetCliCommandResult.Success(stopwatch.Elapsed, outputReader.GetOutputText());
+ }
+
+ // Matches an MSBuild/NuGet warning line, e.g. "...csproj : warning NU1702: ..." or "...targets(1,5): warning NETSDK1138: ...".
+ private static readonly Regex BuildWarningRegex = new(@": warning [A-Za-z]+\d+:", RegexOptions.CultureInvariant | RegexOptions.Compiled);
+
+ // Surfaces just the warning lines from an otherwise-discarded successful build output, deduplicated
+ // (MSBuild repeats a warning per target framework and again in the summary).
+ private static void LogBuildWarnings(ILogger logger, ImmutableArray outputLines)
+ {
+ HashSet? seen = null;
+ foreach (var line in outputLines)
+ {
+ if (!BuildWarningRegex.IsMatch(line))
+ continue;
+
+ string warning = line.Trim();
+ seen ??= new HashSet(StringComparer.Ordinal);
+ if (seen.Add(warning))
+ logger.WriteLineWarning($"// {warning}");
+ }
}
internal static string GetDotNetSdkVersion()
diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs
index 9280c553ef..8c3a41cd73 100644
--- a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs
+++ b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs
@@ -147,9 +147,8 @@ private string GenerateProjectForNuGetBuild(string projectFilePath, BuildPartiti
true
{buildPartition.Platform.ToConfig()}
False
+ false
false
- false
- true
false
true
{ilcOptimizationPreference}
@@ -160,7 +159,6 @@ private string GenerateProjectForNuGetBuild(string projectFilePath, BuildPartiti
false
false
false
- true
{GetInstructionSetSettings(buildPartition)}
{GetRuntimeSettings(buildPartition.RepresentativeBenchmarkCase.Job.Environment.Gc, buildPartition.Resolver)}
diff --git a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs
index 9cc9ffeae0..b04e8d3640 100644
--- a/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs
+++ b/tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks/MultipleFrameworksTest.cs
@@ -14,10 +14,10 @@ public MultipleFrameworksTest(ITestOutputHelper output) : base(output)
}
[Theory]
- [InlineData(RuntimeMoniker.Net461)]
+ [InlineData(RuntimeMoniker.Net462)]
[InlineData(RuntimeMoniker.Net48)]
- [InlineData(RuntimeMoniker.NetCoreApp20)]
[InlineData(RuntimeMoniker.Net80)]
+ [InlineData(RuntimeMoniker.Net10_0)]
public void EachFrameworkIsRebuilt(RuntimeMoniker runtime)
{
var config = ManualConfig.CreateEmpty().AddJob(Job.Dry.WithRuntime(runtime.GetRuntime()).WithEnvironmentVariable(TfmEnvVarName, runtime.ToString()));