[WIP] Enable wasm-tools workload for CoreCLR WASM targets#130226
[WIP] Enable wasm-tools workload for CoreCLR WASM targets#130226lewing wants to merge 7 commits into
Conversation
Add a new 'wasm-tools-coreclr' workload that provides native relinking support for CoreCLR browser-wasm projects without pulling in Mono dependencies (MonoAOTCompiler, MonoTargets.Sdk, Mono runtime pack). Unlike Mono, CoreCLR doesn't need its runtime pack bundled in the workload — the SDK resolves it via the standard KnownRuntimePack mechanism. The workload only provides: - Build targets for native relinking (BrowserWasmApp.CoreCLR.targets) - Emscripten SDK (shared via microsoft-net-sdk-emscripten) Changes: - Package BrowserWasmApp.CoreCLR.targets into WebAssembly.Sdk NuGet pack - Add conditional import in Sdk.targets.in (UseMonoRuntime switches path) - Add wasm-tools-coreclr workload to manifest (no Mono deps) - Add CoreCLR import group in WorkloadManifest.targets.in - Skip MonoAOTCompiler import when UseMonoRuntime=false Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Guard the native.wasm.targets import with a condition so it only loads when RepositoryEngineeringDir is set (in-tree builds). For the workload path, inline the GenerateEmccExports target with the required exported runtime methods and functions. Emscripten SDK acquisition is already handled by EmSdkRepo.Defaults.props + the emscripten workload extension. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Include libminipal.a in browser-wasm CoreCLR runtime pack. It was excluded from LibrariesSharedFrameworkDir glob but unlike libz.a and libSystem.IO.Compression.Native.a it only exists in sharedFramework/ (not the parent LibrariesNativeArtifactsPath), so the exclusion prevented it from shipping at all. libminipal.a is a distinct library from libcoreclrminipal.a and is needed by the emcc linker. - Fix PInvokeTableGeneratorTests to use correct CoreCLR output filename callhelpers-pinvoke.cpp instead of pinvoke-table.cpp. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The _CoreCLRWasmNativeForBuild target must run before _ComputeWasmBuildCandidates (not just _ResolveWasmOutputs) so the relinked dotnet.native.wasm replaces the runtime pack version in the static web assets pipeline. Without this, the runtime pack binary is served and user P/Invoke modules fail with DllNotFoundException. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
During nested publish, _GatherWasmFilesToPublish populates WasmAssembliesToBundle from ResolvedFileToPublish (which includes app satellite assemblies). The CoreCLR build pipeline was calling _GatherWasmFilesToBuild which overwrites this list with build-time items that omit app satellites, causing ComputeWasmPublishAssets to fail. Introduce _CoreCLRGatherWasmFiles wrapper that skips _GatherWasmFilesToBuild during nested publish, preserving the publish-time assembly list. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR prototypes enabling a “CoreCLR browser-wasm” path to use the existing WebAssembly workload/tooling pipeline (Emscripten + relinking + P/Invoke table generation) without pulling in Mono runtime/AOT components, primarily by routing imports/targets based on UseMonoRuntime=false.
Changes:
- Added a new
wasm-tools-coreclrworkload and updated workload target imports to avoid Mono/AOT packs whenUseMonoRuntime == false. - Updated the WebAssembly SDK target selection to import a CoreCLR-specific
BrowserWasmApp.CoreCLR.targetswhenUseMonoRuntime == false. - Adjusted CoreCLR WASM build/publish orchestration and fixed a CoreCLR test expectation for the generated P/Invoke table filename.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs | Updates CoreCLR expectation to callhelpers-pinvoke.cpp for the generated P/Invoke table file. |
| src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in | Guards Mono/AOT imports behind UseMonoRuntime != false and adds a CoreCLR browser-wasm import group for WebAssembly.Sdk only. |
| src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.json.in | Adds the wasm-tools-coreclr workload definition (slimmed to SDK/emscripten packs). |
| src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/Sdk.targets.in | Selects Mono vs CoreCLR browser targets based on UseMonoRuntime. |
| src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Microsoft.NET.Runtime.WebAssembly.Sdk.pkgproj | Ensures BrowserWasmApp.CoreCLR.targets is packed into the SDK. |
| src/mono/browser/build/BrowserWasmApp.CoreCLR.targets | Adds in-tree import guards, inlines emcc exports for workload scenarios, fixes target ordering for build/static web assets, and avoids overwriting publish-time assembly lists during nested publish. |
| eng/liveBuilds.targets | Stops excluding libminipal.a from the CoreCLR browser-wasm runtime pack live-build file set. |
|
We don't really need anything but emsdk for coreclr but I went ahead and matched the wasmsdk logic to avoid getting different versions for the same workload for now. |
Remove the PORTABILITY_ASSERT for indirect struct returns in the CoreCLR WASM interp-to-native thunk generator. For struct return types (S<N> tokens), emit C typedefs of the correct size so emcc generates the proper sret ABI calling convention. This fixes the runtime crash when CoreCLR WASM code calls native functions that return structs. Also remove the native-mono test category filter from EnsureWasmAbiRulesAreFollowedInInterpreter since it now works on CoreCLR. Fixes dotnet#120897 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restore the exclusion of libminipal.a from the LibrariesSharedFrameworkDir glob. The file is already included via CoreCLRSharedFrameworkDir (line 111), so including it from both locations causes NU5118 duplicate file error during nupkg creation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| "packs": [ | ||
| "Microsoft.NET.Runtime.WebAssembly.Sdk.${NetVersion}", | ||
| "Microsoft.NET.Sdk.WebAssembly.Pack.${NetVersion}" | ||
| ], |
There was a problem hiding this comment.
should probably add the coreclr browser-wasm runtime pack here
(and as you know this will need to actually be done in the sdk repo as well)
| TaskFactory="TaskHostFactory" | ||
| Condition="'$(WasmAppBuilderTasksAssemblyPath)' != ''" /> | ||
|
|
||
| <!-- Exported runtime methods and functions for the emcc link step. |
There was a problem hiding this comment.
In Mono we store some of the build/link flags as json file and restore it into MSBuild properties. I don't remember what was our original motivation for that. Maybe DRY ?
Summary
Prototype enabling the
wasm-toolsworkload infrastructure for CoreCLR browser-wasm targets. This allows CoreCLR WASM apps to use the same native relinking pipeline (emcc compile/link, PInvokeTableGenerator) that Mono uses today, without bundling the Mono runtime pack or AOT compiler.Architecture
wasm-tools-coreclrextends onlymicrosoft-net-sdk-emscripten(Emscripten SDK + build targets). No Mono runtime pack or AOT cross-compiler.KnownRuntimePack— no workload override needed (unlike Mono, which must keep runtime pack in lockstep with AOT compiler).UseMonoRuntime=falsein external projects;RuntimeFlavor=CoreCLRin-tree.Changes
WorkloadManifest.json.inwasm-tools-coreclrworkload definitionWorkloadManifest.targets.inSdk.targets.inUseMonoRuntime=falseBrowserWasmApp.CoreCLR.targetseng/liveBuilds.targetslibminipal.aexclusion from CoreCLR browser-wasm runtime packPInvokeTableGeneratorTests.cscallhelpers-pinvoke.cpp)WebAssembly.Sdk.pkgprojBrowserWasmApp.CoreCLR.targetsto SDK packageCI Context
The existing
CoreCLR_WasmBuildTestsCI legs (added by #127073, #128296, #128762) already runDllImportTests,PInvokeTableGeneratorTests,NativeBuildTests,NativeLibraryTests,SatelliteAssembliesTests,IcuTestsand more on CoreCLR — all currently passing on main without workloads (using in-tree build targets). The env vars (RUNTIME_FLAVOR_FOR_TESTS,CORECLR_VM_WASM_INCLUDE_DIR,MINIPAL_INCLUDE_DIR, etc.) are properly wired viaWasm.Build.Tests.csprojRunScriptCommands+RunScriptTemplate.sh.This PR adds the workload packaging so that external consumers (outside the repo) can use the same native relinking pipeline. It also fixes several build pipeline bugs found during validation:
libminipal.amissing from runtime pack — only existed insharedFramework/subdir, was excluded by the glob ineng/liveBuilds.targets_ComputeWasmBuildCandidatesran before native relink completed, freezing stale candidates_GatherWasmFilesToBuildoverwroteWasmAssembliesToBundleduring nested publish, dropping app satellite assembliesRelated Work
Test Results (local validation, non-AOT)
Known expected failures (not regressions)
HandleRefuses Mono-specific ICalls, N/A for CoreCLRPORTABILITY_ASSERT: Indirect struct return(known limitation)precode_portable.cpp:35with[UnmanagedCallersOnly]in namespaced types; Release worksFuture Work
category=workloadtests on CoreCLR (currently excluded via-notraitfilter in csproj line 109)_WasmNativeWorkloadNeededdetection (currently has Mono-specific triggers)Note
This PR description was generated with assistance from GitHub Copilot.