Open
Conversation
d2627a4 to
d7a9bc5
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Implements an in-tree CoreCLR browser-wasm native re-link pipeline (emcc-based) so apps can re-link dotnet.native.wasm against CoreCLR static libs and include custom native code via NativeFileReference.
Changes:
- Replaces stub CoreCLR WASM app targets with a full native compile/link pipeline driven by emcc response files.
- Adjusts build/pack targets to support relink inputs (native assets + JS extern-post-js) and avoid ICU/timezone NuGet content pollution during app-level relink.
- Updates WASM build tests to better support CoreCLR template projects and ensure xharness availability for local runs.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/mono/browser/build/BrowserWasmApp.CoreCLR.targets | Adds the CoreCLR browser-wasm native relink MSBuild pipeline (initialize → generate → compile → link → register assets). |
| eng/native.wasm.targets | Skips ICU/timezone package refs for app-level relink and adjusts multithreading CMake arg logic. |
| src/native/corehost/corehost.proj | Adds runtime-pack copy of libSystem.Native.Browser.extpost.js and new host build CMake arg wiring. |
| src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs | Adds a one-time tool-restore helper to ensure xharness is present locally. |
| src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs | Refactors CoreCLR-specific template property injection; ensures xharness availability; improves Blazor run readiness. |
| src/mono/browser/build/WasmApp.InTree.props | Imports shared WASM props for CoreCLR and sets CoreCLR defaults (incl. WasmBuildNative). |
| src/mono/sample/wasm/Directory.Build.props | Ensures RuntimeFlavor is set early for in-tree sample builds (nested publish correctness). |
Comments suppressed due to low confidence (3)
src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs:236
BootConfigFileNameis part ofMSBuildOptionsand is used by tests (e.g., ModuleConfigTests.OverrideBootConfigName), but the MSBuild invocation no longer adds-p:WasmBootConfigFileName=...when this option is set. This makes the option ineffective and will likely break those tests. Reintroduce passing the property (while still omitting the implicit default when null).
buildOptions.ExtraBuildEnvironmentVariables["TreatPreviousAsCurrent"] = "false";
(CommandResult res, string logFilePath) = BuildProjectWithoutAssert(configuration, info.ProjectName, buildOptions);
src/native/corehost/corehost.proj:92
$(BuildNativeHostTests.ToUpper())/$(BuildNativeHostProduct.ToUpper())is interpreted by MSBuild as a property name containing dots (not a string method call), so this will likely expand to empty and produce-DCLR_CMAKE_BUILD_HOST_TESTS=/-D...PRODUCT=. Use an MSBuild property function instead (e.g.,$([System.String]::Copy('$(BuildNativeHostTests)').ToUpperInvariant())) or pass the lowercase value if CMake accepts it.
<BuildArgs>$(BuildArgs) -cmakeargs "-DCLR_CMAKE_BUILD_HOST_TESTS=$(BuildNativeHostTests.ToUpper())"</BuildArgs>
<BuildArgs>$(BuildArgs) -cmakeargs "-DCLR_CMAKE_BUILD_HOST_PRODUCT=$(BuildNativeHostProduct.ToUpper())"</BuildArgs>
src/native/corehost/corehost.proj:169
- Same issue as above:
$(BuildNativeHostTests.ToUpper())/$(BuildNativeHostProduct.ToUpper())will not callToUpper()in MSBuild and likely expands to empty. Switch to an MSBuild property function (or another explicit transformation) so the CMake definitions receiveTRUE/FALSEas intended.
<BuildArgs>$(BuildArgs) -cmakeargs "-DCLR_CMAKE_BUILD_HOST_TESTS=$(BuildNativeHostTests.ToUpper())"</BuildArgs>
<BuildArgs>$(BuildArgs) -cmakeargs "-DCLR_CMAKE_BUILD_HOST_PRODUCT=$(BuildNativeHostProduct.ToUpper())"</BuildArgs>
pavelsavara
approved these changes
Apr 15, 2026
radekdoulik
approved these changes
Apr 15, 2026
This was referenced Apr 15, 2026
Open
Contributor
|
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Clean PR for original #125607
Summary
Implements the WASM native re-link pipeline for CoreCLR browser-wasm, replacing the stub
WasmBuildApp/WasmTriggerPublishApptargets with a full Emscripten-based native build. This allows CoreCLR WASM apps to include custom native code viaNativeFileReferenceitems by re-linkingdotnet.native.wasmfrom the CoreCLR static libraries shipped in the runtime pack.Changes
src/mono/browser/build/BrowserWasmApp.CoreCLR.targets(+612 lines)The core of this PR. Replaces the two stub targets with a complete native re-link pipeline:
Properties: Sets
IsBrowserWasmProject,TargetsBrowser, forcesWasmEnableExceptionHandling=trueandWasmEnableSIMD=true(CoreCLR requires both), configuresemccas the compiler.Entry points:
WasmBuildApp(after Build) andWasmTriggerPublishApp(after Publish) with nested-publish support matching the Mono pattern.Orchestrator:
_CoreCLRWasmBuildAppCorechains the pipeline stages:_CoreCLRWasmInitialize— validates prerequisites, resolves runtime pack paths, creates intermediate directories._CoreCLRSetupEmscripten— locates the Emscripten SDK (workload orEMSDK_PATH), sets environment variables foremcc._CoreCLRPrepareForNativeBuild— resolves optimization flags, collectsNativeFileReferenceitems, builds compile flags (always includes-fwasm-exceptions -msimd128)._CoreCLRGenerateManagedToNative— runsManagedToNativeGeneratorto produce P/Invoke and interp-to-native tables from managed assemblies._CoreCLRWriteCompileRsp— generates acoreclr_compat.hheader with type/macro stubs (MethodDesc,PCODE,LOG,PORTABILITY_ASSERT, etc.) so ManagedToNativeGenerator output compiles outside the full CoreCLR build context. Writes the compile response file._CoreCLRCompileNativeSources— invokesEmccCompileon user sources and generated tables._CoreCLRWriteLinkRsp— builds linker arguments mirroringbrowserhost/CMakeLists.txt: CoreCLR static libraries (libBrowserHost.a,libcoreclr_static.a,libcoreclrpal.a, etc.), JS libraries, ES6 module settings, memory configuration, exported functions/runtime methods._CoreCLRLinkNative— invokesemccwith the link response file, producingdotnet.native.js,dotnet.native.wasm, and symbol maps._CoreCLRCompleteNativeBuild— replaces pre-built runtime pack native assets with the re-linked versions._CoreCLREmitAssembliesFinal— emits the final managed assembly list with satellite assembly handling.Validates that users cannot disable EH or SIMD (errors out with a clear message).
Supports incremental builds via
Inputs/Outputson the link target.Supports Debug/Release optimization flags (
-O0/-O1/-O2).Respects
InvariantGlobalizationandInvariantTimezoneto skip ICU/timezone libraries.eng/native.wasm.targets(+5/-1)Adds
Condition="'$(IsBrowserWasmProject)' != 'true'"to the ICU and timezone NuGetPackageReferenceitems. During app-level relink the runtime pack already contains the pre-built native files; pulling in these packages at app build time would inject theircontentFiles(timezone data files, READMEs) into the app'sContentitems, causing VFS / StaticWebAssets validation failures.src/native/corehost/corehost.proj(+2)Adds
libSystem.Native.Browser.extpost.jsto the list of files copied into the runtime pack's native directory. This JS file is required by the emcc linker during per-app native relinking (it's referenced as--extern-post-jsin the link arguments).src/mono/wasm/Wasm.Build.Tests/BuildTestBase.cs(+60)Adds
EnsureXHarnessAvailable()— a thread-safe helper that runsdotnet tool restoreonce per test process whenXHARNESS_CLI_PATHis not set (local dev scenario). Prevents test failures caused by missing xharness CLI when running browser tests locally.src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs(+39/-28)UseMonoRuntime=false,UsingBrowserRuntimeWorkload=false,KnownFrameworkReference/KnownWebAssemblySdkPackupdates) into a reusableAddCoreClrProjectProperties()method.CreateWasmTemplateProjectandCopyTestAsset, fixing a gap where template-created projects were missing the CoreCLR properties.EnsureXHarnessAvailable()before browser test runs.Architecture
The pipeline mirrors the existing Mono WASM native build but is adapted for CoreCLR's different static library set and requirements:
Key differences from Mono WASM native build
-fwasm-exceptionsand-msimd128; user cannot disable them.libBrowserHost.a,libcoreclr_static.a,libcoreclrpal.a, etc. instead oflibmonosgen-2.0.a.coreclr_compat.hwith type stubs soManagedToNativeGeneratoroutput (which references CoreCLR internals likeMethodDesc,PCODE) compiles in the app build context without the full CoreCLR source tree.src/native/corehost/browserhost/CMakeLists.txtrather than the Mono wasm build.Contributes to #123670
Contributes to #126100