Uh oh!
There was an error while loading. Please reload this page.
[browser] CoreCLR in-tree relink - #126946
Conversation
d2627a4 to
d7a9bc5CompareThere 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>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
This comment was marked as resolved.
This comment was marked as resolved.
…eparators $(WasmDirSep) is never defined anywhere in the codebase, causing the fallback glob for System.Runtime.dll to produce an invalid path like 'libnet*System.Runtime.dll' instead of 'lib/net*/System.Runtime.dll'. Use backslash separators matching the Mono equivalent in WasmApp.Common.targets (MSBuild normalizes to the platform separator). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
maraf
commented
Apr 17, 2026
/ba-g Failures are not related to this PR. All failing jobs match pre-existing known issues affecting many PRs across the repo.
Note This comment was generated with the assistance of GitHub Copilot. |
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