Skip to content

Wasm tests use Microsoft.NET.Sdk.WebAssembly and support CoreClr runtime#2998

Merged
timcassell merged 14 commits intodotnet:masterfrom
ilonatommy:wasm-tests-use-wasm-sdk
Feb 16, 2026
Merged

Wasm tests use Microsoft.NET.Sdk.WebAssembly and support CoreClr runtime#2998
timcassell merged 14 commits intodotnet:masterfrom
ilonatommy:wasm-tests-use-wasm-sdk

Conversation

@ilonatommy
Copy link
Member

@ilonatommy ilonatommy commented Feb 11, 2026

Problem

The autogenerated benchmark project uses Microsoft.NET.Sdk, which does not set UseMonoRuntime=true. This causes ProcessFrameworkReferences to resolve the CoreCLR runtime pack (Microsoft.NETCore.App.Runtime.browser-wasm) instead of the Mono one (Microsoft.NETCore.App.Runtime.Mono.browser-wasm). The CoreCLR pack does not exist for browser-wasm, so the build fails.

PR #2994 worked around this by adding -r browser-wasm to the restore command, but this only defers the error — the runtime pack is still not resolved correctly during build.

Fix

Switch the default SDK to Microsoft.NET.Sdk.WebAssembly, which auto-defaults UseMonoRuntime=true and resolves the correct Mono runtime pack. Add IsMonoRuntime flag to WasmRuntime so users can opt into the CoreCLR runtime pack (--wasmCoreCLR CLI flag), which falls back to Microsoft.NET.Sdk.

Changes

  • SDK switch: Default to Microsoft.NET.Sdk.WebAssembly (Mono). When IsMonoRuntime=false, use Microsoft.NET.Sdk (CoreCLR).
  • --wasmCoreCLR CLI flag: New option to select the CoreCLR runtime pack for WASM benchmarks.
  • DotNetCliPublisher: WASM toolchain now uses DotNetCliPublisher instead of DotNetCliBuilder, matching the template's DefaultTargets="publish" and eliminating the ForcedNoDependencies workaround.
  • ArtifactsPath fix: Point ArtifactsPath to a .artifacts/ subdirectory so DefaultItemExcludes ($(ArtifactsPath)/**) doesn't exclude wwwroot/ from Content globs.
  • Embed benchmark-main.mjs: Entry point is now an embedded template resource placed into wwwroot/ during generation, replacing the AppBundle/test-main.js test asset.
  • MainJS constant: Remove dead net5.0/net6.0 code path.
  • Remove: -r browser-wasm from restore, WasmGenerateRunV8Script, WasmMainJSPath dependency.

Testing

Integration tests: 4/4 WasmTests pass (net8.0, AOT + Interpreter × V8 + JSC)
benchmarks_ci.py: 5/5 Perf_Boolean.Parse benchmarks pass on Wasm AOT

@maraf
Copy link
Member

maraf commented Feb 12, 2026

The failure is caused by the fact that autogenerated project uses Microsoft.NET.Sdk and thus, keeps UseMonoRuntime=false by default. As a result, restore tries to download clr runtime, not mono runtime.

Instead of explicitly passing UseMonoRuntime, we should disable runtime/targeting pack download, similar to dotnet/runtime#124288

@ilonatommy
Copy link
Member Author

Instead of explicitly passing UseMonoRuntime, we should disable runtime/targeting pack download, similar to dotnet/runtime#124288

We don't pass it explicitly. We decided to change the sdk type instead, to change the value UseMonoRuntime defaults to.

@ilonatommy ilonatommy marked this pull request as ready for review February 13, 2026 07:19
@ilonatommy ilonatommy changed the title Wasm tests use Microsoft.NET.Sdk.WebAssembly Wasm tests use Microsoft.NET.Sdk.WebAssembly and support CoreClr runtime Feb 13, 2026
Require --output (BuildPartition.cs) — WASM needs explicit output paths because the WebAssembly SDK publishes to wwwroot/ inside the output directory. Without --output, build artifacts land in the default bin/ tree where the executor doesn't look.

excludeArtifactsPath (DotNetCliCommand.cs) — BDN normally passes /p:ArtifactsPath to redirect output. But the SDK auto-sets UseArtifactsOutput=true when ArtifactsPath is non-empty, which adds $(ArtifactsPath)/** to DefaultItemExcludes — excluding every file in the project directory (including wwwroot/) from default Content globs. For WASM, we pass /p:UseArtifactsOutput=false instead, since OutDir/OutputPath/--output already control where output goes.

Content Update (WasmCsProj.txt) — With UseArtifactsOutput=false, the SDK's default <Content Include="wwwroot\**" ...> glob works, so Content Update can upgrade those items with CopyToOutputDirectory=PreserveNewest.
Copy link
Collaborator

@timcassell timcassell left a comment

Choose a reason for hiding this comment

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

Thanks @ilonatommy

@timcassell timcassell merged commit 7563eb4 into dotnet:master Feb 16, 2026
11 checks passed
@timcassell timcassell added this to the v0.16.0 milestone Feb 16, 2026
@timcassell
Copy link
Collaborator

Did these changes break WasmNet50-WasmNet70? We don't have any CI coverage of those, and copilot is saying that the new mjs template is incompatible with the older tfms. If that's the case, I don't think it's worth continuing to support them, and we should probably just remove those monikers.

@ilonatommy
Copy link
Member Author

Did these changes break WasmNet50-WasmNet70? We don't have any CI coverage of those, and copilot is saying that the new mjs template is incompatible with the older tfms. If that's the case, I don't think it's worth continuing to support them, and we should probably just remove those monikers.

What are the failures, where can I see them? I am not sure about the theory of no support. dotnet/runtime#61313, dotnet/runtime#62292 are in .net 7 and imply modules were working then already.

@ilonatommy
Copy link
Member Author

Sorry, I misunderstood. It could have broken WasmNet50-WasmNet60 but not WasmNet70. Regardless of that, removing monikers for WasmNet50-WasmNet70 sounds reasonable.

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