Skip to content

Fix WASM workload detection for non-Blazor/WasmSdk Exe projects#52677

Open
DrewScoggins wants to merge 2 commits intodotnet:mainfrom
DrewScoggins:fix/wasm-workload-detection-exe-projects
Open

Fix WASM workload detection for non-Blazor/WasmSdk Exe projects#52677
DrewScoggins wants to merge 2 commits intodotnet:mainfrom
DrewScoggins:fix/wasm-workload-detection-exe-projects

Conversation

@DrewScoggins
Copy link
Member

This fixes an issue where BenchmarkDotNet-generated WASM benchmark projects stopped working after commit 34e2468 removed the _UsingBlazorOrWasmSdk condition from _WasmNativeWorkloadNeeded.

The change in that commit was intended to allow library projects with RuntimeIdentifier=browser-wasm to build without requiring the WASM workload (per dotnet/runtime#122607). However, the change was too broad - it affected ALL non-Blazor/WasmSdk projects, including Exe projects that need the workload for runtime pack resolution.

This fix adds back the workload requirement specifically for Exe projects that don't use Blazor/WasmSdk, while preserving the library-mode-without-workload behavior.

Changes:

  • WorkloadManifest.targets.in: Added condition to set _WasmNativeWorkloadNeeded for Exe projects without BlazorOrWasmSdk
  • Added regression tests to verify:
    • Exe projects trigger workload usage (UsingBrowserRuntimeWorkload=true)
    • Library projects don't force workload usage
    • Runtime pack version is available when workload is used
  • Added test asset WasmConsoleApp for the test scenarios

Fixes the 'MicrosoftNetCoreAppRuntimePackDir is empty' error in WASM benchmarks.

This fixes an issue where BenchmarkDotNet-generated WASM benchmark projects
stopped working after commit 34e2468 removed the _UsingBlazorOrWasmSdk
condition from _WasmNativeWorkloadNeeded.

The change in that commit was intended to allow library projects with
RuntimeIdentifier=browser-wasm to build without requiring the WASM workload
(per dotnet/runtime#122607). However, the change was too broad - it affected
ALL non-Blazor/WasmSdk projects, including Exe projects that need the workload
for runtime pack resolution.

This fix adds back the workload requirement specifically for Exe projects that
don't use Blazor/WasmSdk, while preserving the library-mode-without-workload
behavior.

Changes:
- WorkloadManifest.targets.in: Added condition to set _WasmNativeWorkloadNeeded
  for Exe projects without BlazorOrWasmSdk
- Added regression tests to verify:
  - Exe projects trigger workload usage (UsingBrowserRuntimeWorkload=true)
  - Library projects don't force workload usage
  - Runtime pack version is available when workload is used
- Added test asset WasmConsoleApp for the test scenarios

Fixes the 'MicrosoftNetCoreAppRuntimePackDir is empty' error in WASM benchmarks.
@DrewScoggins
Copy link
Member Author

This fix came out of discussion with Copilot. Let me know if the tests don't match up with what y'all do in this repo.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an issue where WASM workload detection was broken for non-Blazor/WasmSdk Exe projects (such as those generated by BenchmarkDotNet). The previous change that allowed library projects targeting browser-wasm to build without the workload inadvertently affected all non-Blazor/WasmSdk projects, including Exe projects that require the workload for runtime pack resolution.

Changes:

  • Added a condition to require the WASM workload for Exe projects that don't use Blazor/WasmSdk
  • Added comprehensive test coverage to verify workload behavior for both Exe and library projects
  • Added test asset files for WasmConsoleApp (though not used by the automated tests)

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
WorkloadManifest.targets.in Adds condition to set _WasmNativeWorkloadNeeded=true for Exe projects without Blazor/WasmSdk, preserving library-mode-without-workload behavior
WasmWorkloadDetectionTests.cs New test class with three tests covering Exe workload requirement, library non-requirement, and runtime pack version availability
WasmConsoleApp/WasmConsoleApp.csproj Test asset project file for WASM console app (not used in automated tests)
WasmConsoleApp/Program.cs Test asset source file with simple console output (not used in automated tests)
WasmConsoleApp/main.js Test asset JavaScript entry point (not used in automated tests, contains reference to non-existent Greeting method)

{
/// <summary>
/// Tests for WASM workload detection with projects using Microsoft.NET.Sdk (not Blazor/WebAssembly SDK).
/// These tests verify the fix for https://github.com/dotnet/sdk/issues/XXXXX where BenchmarkDotNet
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The placeholder issue number "XXXXX" should be replaced with the actual GitHub issue number.

Suggested change
/// These tests verify the fix for https://github.com/dotnet/sdk/issues/XXXXX where BenchmarkDotNet
/// These tests verify the fix for a bug where BenchmarkDotNet

Copilot uses AI. Check for mistakes.
@DrewScoggins
Copy link
Member Author

Just to be clear, this is currently blocking our ability to collect performance results on WASM.

<!-- Exe projects targeting browser-wasm without Blazor/WasmSdk need the workload for runtime pack resolution.
This ensures tools like BenchmarkDotNet that generate WASM console apps work correctly.
Library projects can build without the workload (they don't need AppBundle generation). -->
<_WasmNativeWorkloadNeeded Condition="'$(_UsingBlazorOrWasmSdk)' != 'true' and '$(OutputType)' == 'Exe'">true</_WasmNativeWorkloadNeeded>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add and '$(_WasmNativeWorkloadNeeded)' == ''

@pavelsavara
Copy link
Member

@maraf has this in progress dotnet/runtime#122607 I wonder if it's the solution for the same or similar problem

@pavelsavara
Copy link
Member

pavelsavara commented Jan 27, 2026

Also much more localized solution could be to add <WasmBuildNative>true</WasmBuildNative> into the benchmark project.

Edit: hmm, it's already there

https://github.com/dotnet/performance/blob/43d3453263242e0d0a2adb8a70cac45184cba836/src/benchmarks/micro/MicroBenchmarks.Wasm.props#L7

@pavelsavara
Copy link
Member

pavelsavara commented Jan 27, 2026

Looking at Log and Binlog

[2026/01/27 08:20:35][INFO] .NET workloads installed:
[2026/01/27 08:20:35][INFO]  [wasm-tools]
[2026/01/27 08:20:35][INFO]    Installation Source: SDK 11.0.100-alpha.1
[2026/01/27 08:20:35][INFO]    Manifest Version:    11.0.0-ci/11.0.100-alpha.1
[2026/01/27 08:20:35][INFO]    Manifest Path:       /home/helixbot/work/BFC309E4/p/dotnet/sdk-manifests/11.0.100-alpha.1/microsoft.net.workload.mono.toolchain.current/WorkloadManifest.json
[2026/01/27 08:20:35][INFO]    Install Type:        FileBased
[2026/01/27 08:20:35][INFO] 
[2026/01/27 08:20:35][INFO]  [wasm-experimental]
[2026/01/27 08:20:35][INFO]    Installation Source: SDK 11.0.100-alpha.1
[2026/01/27 08:20:35][INFO]    Manifest Version:    11.0.0-ci/11.0.100-alpha.1
[2026/01/27 08:20:35][INFO]    Manifest Path:       /home/helixbot/work/BFC309E4/p/dotnet/sdk-manifests/11.0.100-alpha.1/microsoft.net.workload.mono.toolchain.current/WorkloadManifest.json
[2026/01/27 08:20:35][INFO]    Install Type:        FileBased
[2026/01/27 08:21:12][INFO]   Optimizing assemblies for size. This process might take a while.
[2026/01/27 08:21:21][INFO] /home/helixbot/work/BFC309E4/p/dotnet/packs/Microsoft.NET.Runtime.WebAssembly.Sdk/11.0.0-ci/Sdk/ILLink.Substitutions.WasmIntrinsics.xml(2,4): warning IL2007: Could not resolve assembly 'System.Private.CoreLib'. [/home/helixbot/work/BFC309E4/w/B2F20A0A/e/performance/artifacts/bin/for-running/MicroBenchmarks/MicroBenchmarks-Wasm-1/BenchmarkDotNet.Autogenerated.csproj::TargetFramework=net11.0]
[2026/01/27 08:21:21][INFO] /home/helixbot/work/BFC309E4/w/B2F20A0A/e/performance/src/benchmarks/micro/ILLink.Descriptors.Serialization.xml(2,4): 
warning IL2007: Could not resolve assembly 'System.Private.DataContractSerialization'. [/home/helixbot/work/BFC309E4/w/B2F20A0A/e/performance/artifacts/bin/for-running/MicroBenchmarks/MicroBenchmarks-Wasm-1/BenchmarkDotNet.Autogenerated.csproj::TargetFramework=net11.0]
[2026/01/27 08:21:36][INFO] /home/helixbot/work/BFC309E4/p/dotnet/packs/Microsoft.NET.Runtime.WebAssembly.Sdk/11.0.0-ci/Sdk/WasmApp.Common.targets(286,5): 
error : $(MicrosoftNetCoreAppRuntimePackDir)='', and cannot find %(ResolvedRuntimePack.PackageDirectory)=. 
One of these need to be set to a valid path 
[/home/helixbot/work/BFC309E4/w/B2F20A0A/e/performance/artifacts/bin/for-running/MicroBenchmarks/MicroBenchmarks-Wasm-1/BenchmarkDotNet.Autogenerated.csproj::TargetFramework=net11.0]
[2026/01/27 08:21:36][INFO] Build FAILED.

@pavelsavara
Copy link
Member

image image

@pavelsavara
Copy link
Member

So far I think this is about missing runtime pack.

WasmApp.Common.targets(286,5): error : $(MicrosoftNetCoreAppRuntimePackDir)='', and cannot find %(ResolvedRuntimePack.PackageDirectory)

Probably nuget of the right version is not yet in the right feed ?

@lewing
Copy link
Member

lewing commented Feb 3, 2026

So far I think this is about missing runtime pack.

WasmApp.Common.targets(286,5): error : $(MicrosoftNetCoreAppRuntimePackDir)='', and cannot find %(ResolvedRuntimePack.PackageDirectory)

Probably nuget of the right version is not yet in the right feed ?

is this just becase UseMonoRuntime isn't set?

@maraf
Copy link
Member

maraf commented Feb 9, 2026

is this just becase UseMonoRuntime isn't set?

The problem is that dotnet/perf doesn't use WasmSDK and we don't have the former bundler anymore. WIP in dotnet/performance#5101

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Comments