From 13c986f62ce79713df482f6af0c65c8fa7172f8c Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Fri, 14 Aug 2026 21:01:34 +0200 Subject: [PATCH 1/3] Enable crossgen2 to target browser-wasm/wasi-wasm ResolveReadyToRunCompilers: add wasm architecture and browser/wasi OS so the SDK can resolve the crossgen2 pack for wasm. Dual-install clrjit_universal_wasm_* into the alljits component so the shipped Microsoft.NETCore.App.Crossgen2. pack carries the wasm cross-JIT (crossgen2 v6+ auto-loads it from tools/). Assisted-by: GitHub Copilot --- src/coreclr/jit/CMakeLists.txt | 2 +- src/tasks/Crossgen2Tasks/ResolveReadyToRunCompilers.cs | 10 +++++++++- src/tasks/Crossgen2Tasks/RunReadyToRunCompiler.cs | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/CMakeLists.txt b/src/coreclr/jit/CMakeLists.txt index 7e9791ebe60adb..3999593c2bbca1 100644 --- a/src/coreclr/jit/CMakeLists.txt +++ b/src/coreclr/jit/CMakeLists.txt @@ -697,7 +697,7 @@ function(add_jit jitName) # add the install targets if (${jitName} MATCHES "clrjit_universal_wasm") - # TODO-WASM: add the WASM Jit to alljits once that becomes necessary. + install_clr(TARGETS ${jitName} DESTINATIONS . COMPONENT alljits) install_clr(TARGETS ${jitName} DESTINATIONS . COMPONENT wasmjit) else() install_clr(TARGETS ${jitName} DESTINATIONS . COMPONENT alljits) diff --git a/src/tasks/Crossgen2Tasks/ResolveReadyToRunCompilers.cs b/src/tasks/Crossgen2Tasks/ResolveReadyToRunCompilers.cs index d487eb995a396b..684d1d84639c97 100644 --- a/src/tasks/Crossgen2Tasks/ResolveReadyToRunCompilers.cs +++ b/src/tasks/Crossgen2Tasks/ResolveReadyToRunCompilers.cs @@ -210,7 +210,7 @@ private bool GetCrossgen2TargetOS(out string targetOS) string portablePlatform = NuGetUtils.GetBestMatchingRid( runtimeGraph, _targetRuntimeIdentifier, - new[] { "linux", "android", "osx", "win", "freebsd", "illumos" }, + new[] { "linux", "android", "osx", "win", "freebsd", "illumos", "browser", "wasi" }, out _); targetOS = portablePlatform switch @@ -221,6 +221,8 @@ private bool GetCrossgen2TargetOS(out string targetOS) "win" => "windows", "freebsd" => "freebsd", "illumos" => "illumos", + "browser" => "browser", + "wasi" => "wasi", _ => null }; @@ -280,6 +282,11 @@ private static bool ExtractTargetPlatformAndArchitecture(string runtimeIdentifie case "x86": architecture = Architecture.X86; break; +#if !NETFRAMEWORK + case "wasm": + architecture = Architecture.Wasm; + break; +#endif default: return false; } @@ -444,6 +451,7 @@ private static string ArchitectureToString(Architecture architecture) #if !NETFRAMEWORK Architecture.RiscV64 => "riscv64", Architecture.LoongArch64 => "loongarch64", + Architecture.Wasm => "wasm", #endif _ => null }; diff --git a/src/tasks/Crossgen2Tasks/RunReadyToRunCompiler.cs b/src/tasks/Crossgen2Tasks/RunReadyToRunCompiler.cs index 22045ddd145fdf..ed514da93a8eaf 100644 --- a/src/tasks/Crossgen2Tasks/RunReadyToRunCompiler.cs +++ b/src/tasks/Crossgen2Tasks/RunReadyToRunCompiler.cs @@ -23,6 +23,7 @@ public class RunReadyToRunCompiler : ToolTask public bool ShowCompilerWarnings { get; set; } public bool UseCrossgen2 { get; set; } public string Crossgen2ExtraCommandLineArgs { get; set; } + public string Crossgen2CompositeExtraCommandLineArgs { get; set; } public ITaskItem[] Crossgen2PgoFiles { get; set; } public string Crossgen2ContainerFormat { get; set; } From 23f07753ac796ba499a602141c6ab03fa8e5edec Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Fri, 14 Aug 2026 21:01:41 +0200 Subject: [PATCH 2/3] Ship prebuilt framework ReadyToRun images in the browser-wasm runtime pack Crossgen each shared-framework assembly to a webcil-in-wasm R2R image under runtimes/browser-wasm/native/r2r/, keeping the IL in lib/ (the CoreLib model generalized to the whole framework). CoreLib.wasm comes from the coreclr build. WasmFrameworkR2RSubset limits the set for bring-up. Nothing consumes these yet; the SDK integration is a follow-up commit. See dotnet/runtime#121257. Assisted-by: GitHub Copilot --- ...rosoft.NETCore.App.Runtime.CoreCLR.sfxproj | 65 ++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj index 45a5d877f608a9..a78066f5fdb16a 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj @@ -26,7 +26,8 @@ true false - + false false true @@ -64,6 +65,68 @@ + + + true + <_WasmFrameworkR2RDir>$([MSBuild]::NormalizeDirectory('$(IntermediateOutputPath)', 'framework-r2r')) + + + + + <_WasmFrameworkR2RInput Include="$(LibrariesSharedFrameworkBinArtifactsPath)*.dll" + Exclude="$(LibrariesSharedFrameworkBinArtifactsPath)*.resources.dll" /> + + <_WasmFrameworkR2RInput Remove="@(_WasmFrameworkR2RInput)" + Condition="'$(WasmFrameworkR2RSubset)' != '' and !$([System.String]::Copy(';$(WasmFrameworkR2RSubset);').Contains(';%(FileName);'))" /> + <_WasmFrameworkR2RInput> + $(_WasmFrameworkR2RDir)%(FileName).wasm + + + + <_WasmCoreLibIL Condition="Exists('$(CoreCLRArtifactsPath)System.Private.CoreLib.dll')">$(CoreCLRArtifactsPath)System.Private.CoreLib.dll + <_WasmCoreLibIL Condition="'$(_WasmCoreLibIL)' == '' and Exists('$(CoreCLRArtifactsPath)IL\System.Private.CoreLib.dll')">$(CoreCLRArtifactsPath)IL\System.Private.CoreLib.dll + <_WasmCrossgen2Exe>$([MSBuild]::NormalizePath('$(Crossgen2InBuildDir)', 'crossgen2$(ExeSuffix)')) + + + + + + + + + + + + + <_WasmFrameworkR2ROutput Include="$(_WasmFrameworkR2RDir)*.wasm" /> + <_WasmFrameworkR2ROutput Include="$(CoreCLRArtifactsPath)System.Private.CoreLib.wasm" + Condition="Exists('$(CoreCLRArtifactsPath)System.Private.CoreLib.wasm')" /> + + + + + + + + + <_WasmManagedAssembliesR2RRemap Include="@(_WasmManagedAssemblies)" Condition="Exists('$(IntermediateLinkDir)%(FileName)%(Extension)')" /> + <_WasmManagedAssemblies Remove="@(_WasmManagedAssembliesR2RRemap)" /> + <_WasmManagedAssemblies Include="@(_WasmManagedAssembliesR2RRemap->'$(IntermediateLinkDir)%(FileName)%(Extension)')" /> + + <_HasCoreLib Condition="'%(_WasmManagedAssemblies.FileName)%(_WasmManagedAssemblies.Extension)' == 'System.Private.CoreLib.dll'">true diff --git a/src/mono/browser/build/WasmApp.InTree.props b/src/mono/browser/build/WasmApp.InTree.props index 2eb17ec0c0f94c..09f0d33488a0ce 100644 --- a/src/mono/browser/build/WasmApp.InTree.props +++ b/src/mono/browser/build/WasmApp.InTree.props @@ -24,6 +24,15 @@ true + + + $(AfterMicrosoftNETSdkTargets);$(Crossgen2SdkOverrideTargetsPath) + $(AfterMicrosoftNETSdkTargets);$(MSBuildThisFileDirectory)WasmApp.ReadyToRun.targets + + + library diff --git a/src/mono/browser/build/WasmApp.ReadyToRun.targets b/src/mono/browser/build/WasmApp.ReadyToRun.targets new file mode 100644 index 00000000000000..1194acbb46f69d --- /dev/null +++ b/src/mono/browser/build/WasmApp.ReadyToRun.targets @@ -0,0 +1,18 @@ + + + + + $([MSBuild]::NormalizePath('$(Crossgen2InBuildDir)', 'crossgen2$(ExeSuffix)')) + + + + + + + diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.CoreCLR.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.CoreCLR.targets new file mode 100644 index 00000000000000..fd6d1ffa9e0bbb --- /dev/null +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.CoreCLR.targets @@ -0,0 +1,95 @@ + + + + + + true + + + + + wasm + false + + $(PublishReadyToRunCrossgen2ExtraArgs);--codegenopt:JitWasmNyiToR2RUnsupported=1;--codegenopt:JitWasmSimdNyiToR2RUnsupported=1 + + + + + + <_WasmPackR2RDir Condition="'$(_WasmPackR2RDir)' == '' and '$(_RuntimePackNativeDir)' != ''">$([MSBuild]::NormalizeDirectory('$(_RuntimePackNativeDir)', 'r2r')) + + + <_WasmPublishR2RDir Condition="'$(_WasmPublishR2RDir)' == ''">$([MSBuild]::NormalizeDirectory('$(IntermediateOutputPath)', 'R2R')) + <_WasmBuildPrebuiltR2RDirectories>$(_WasmPackR2RDir) + <_WasmPublishPrebuiltR2RDirectories Condition="'$(PublishTrimmed)' == 'true'">$(_WasmPublishR2RDir) + <_WasmPublishPrebuiltR2RDirectories Condition="'$(PublishTrimmed)' != 'true'">$(_WasmPackR2RDir) + + + + + + + + + + + + + + + + + + + + + + + + + <_WasmReadyToRunCompileInput Include="$(IntermediateLinkDir)*.dll" /> + + + + + + + + diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets index 4ec8ade0ed5c92..b2ce682bb412bd 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets @@ -421,7 +421,7 @@ Copyright (c) .NET Foundation. All rights reserved. Inputs="@(_WasmDllBuildCandidates);$(MSBuildProjectFullPath);$(MSBuildThisFileFullPath);$(_WebAssemblySdkTasksAssembly)" Outputs="@(_WasmDllBuildCandidates->'%(WebcilOutputPath)')"> - + @@ -1010,7 +1010,7 @@ Copyright (c) .NET Foundation. All rights reserved. <_WasmPublishTmpWebcilPath>$([MSBuild]::NormalizeDirectory($(IntermediateOutputPath), 'tmp-webcil', 'publish')) - + @@ -1358,4 +1358,8 @@ Copyright (c) .NET Foundation. All rights reserved. + + + diff --git a/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj b/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj index 365a61629523a8..4e60eba8c42df9 100644 --- a/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj +++ b/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj @@ -21,6 +21,7 @@ <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --dump-dependencies