Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/jit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
<PublishReadyToRun>true</PublishReadyToRun>
<!-- Disable crossgen on NetBSD, illumos, Solaris and Haiku for now. This can be revisited when we have full support. -->
<PublishReadyToRun Condition="'$(TargetOS)' == 'netbsd' or '$(TargetOS)' == 'illumos' or '$(TargetOS)' == 'solaris' or '$(TargetOS)' == 'haiku'">false</PublishReadyToRun>
<!-- TODO-WASM: we will have WASM R2R after https://github.com/dotnet/runtime/issues/121257 -->
<!-- TODO-WASM: WASM framework R2R needs the CoreLib model (native/*.wasm webcil + kept lib/*.dll IL),
not the SDK's in-place R2R which replaces lib/*.dll. See dotnet/runtime#121257. -->
<PublishReadyToRun Condition="'$(TargetOS)' == 'browser' or '$(TargetOS)' == 'wasi'">false</PublishReadyToRun>
<PublishReadyToRun Condition="'$(StageTwoBuild)'=='true'">false</PublishReadyToRun>
<UsesMuxerHostModel Condition="'$(TargetsMobile)' != 'true'">true</UsesMuxerHostModel>
Expand Down Expand Up @@ -64,6 +65,68 @@
</PropertyGroup>
</Target>

<!--
WASM framework R2R: crossgen each shared-framework assembly to a webcil-in-wasm R2R image under the
pack native/r2r/, keeping the IL in lib/ (the CoreLib model generalized; the SDK's in-place R2R can't
be used as it drops the IL). See PR.md / dotnet/runtime#121257. WasmFrameworkR2RSubset limits the set.
-->
<PropertyGroup Condition="'$(TargetsBrowser)' == 'true' and '$(RuntimeFlavor)' == 'CoreCLR'">
<WasmEnableFrameworkR2R Condition="'$(WasmEnableFrameworkR2R)' == ''">true</WasmEnableFrameworkR2R>
<_WasmFrameworkR2RDir>$([MSBuild]::NormalizeDirectory('$(IntermediateOutputPath)', 'framework-r2r'))</_WasmFrameworkR2RDir>
</PropertyGroup>

<Target Name="_ComputeBrowserFrameworkR2RInputs"
Condition="'$(WasmEnableFrameworkR2R)' == 'true'"
DependsOnTargets="ResolveLibrariesFromLocalBuild;ResolveRuntimeFilesFromLocalBuild">
<ItemGroup>
<_WasmFrameworkR2RInput Include="$(LibrariesSharedFrameworkBinArtifactsPath)*.dll"
Exclude="$(LibrariesSharedFrameworkBinArtifactsPath)*.resources.dll" />
<!-- Optional subset filter for bring-up: keep only assemblies named in WasmFrameworkR2RSubset. -->
<_WasmFrameworkR2RInput Remove="@(_WasmFrameworkR2RInput)"
Condition="'$(WasmFrameworkR2RSubset)' != '' and !$([System.String]::Copy(';$(WasmFrameworkR2RSubset);').Contains(';%(FileName);'))" />
<_WasmFrameworkR2RInput>
<OutputWasm>$(_WasmFrameworkR2RDir)%(FileName).wasm</OutputWasm>
</_WasmFrameworkR2RInput>
</ItemGroup>
<PropertyGroup>
<_WasmCoreLibIL Condition="Exists('$(CoreCLRArtifactsPath)System.Private.CoreLib.dll')">$(CoreCLRArtifactsPath)System.Private.CoreLib.dll</_WasmCoreLibIL>
<_WasmCoreLibIL Condition="'$(_WasmCoreLibIL)' == '' and Exists('$(CoreCLRArtifactsPath)IL\System.Private.CoreLib.dll')">$(CoreCLRArtifactsPath)IL\System.Private.CoreLib.dll</_WasmCoreLibIL>
<_WasmCrossgen2Exe>$([MSBuild]::NormalizePath('$(Crossgen2InBuildDir)', 'crossgen2$(ExeSuffix)'))</_WasmCrossgen2Exe>
</PropertyGroup>
</Target>

<Target Name="_CrossgenBrowserFrameworkR2R"
Condition="'$(WasmEnableFrameworkR2R)' == 'true'"
DependsOnTargets="_ComputeBrowserFrameworkR2RInputs"
Inputs="@(_WasmFrameworkR2RInput);$(_WasmCoreLibIL)"
Outputs="@(_WasmFrameworkR2RInput->'%(OutputWasm)')">
<MakeDir Directories="$(_WasmFrameworkR2RDir)" />
<Message Importance="High" Text="Crossgen R2R (wasm): %(_WasmFrameworkR2RInput.FileName)" />
<Exec Condition="Exists('$(_WasmCrossgen2Exe)')"
Command="&quot;$(_WasmCrossgen2Exe)&quot; -o:&quot;%(_WasmFrameworkR2RInput.OutputWasm)&quot; -r:&quot;$(LibrariesSharedFrameworkBinArtifactsPath)*.dll&quot; -r:&quot;$(_WasmCoreLibIL)&quot; --targetarch:$(TargetArchitecture) --targetos:$(TargetOS) --obj-format:wasm --codegenopt:JitWasmNyiToR2RUnsupported=1 --codegenopt:JitWasmSimdNyiToR2RUnsupported=1 -O &quot;%(_WasmFrameworkR2RInput.FullPath)&quot;" />
Comment on lines +91 to +106
</Target>

<!-- No Inputs/Outputs so images are packed even when crossgen was incrementally skipped. native/r2r is a
dedicated subfolder (no collision with dotnet.native.wasm / served webcils). CoreLib.wasm comes from
the coreclr build (crossgen-corelib), not this loop. -->
<Target Name="_AddBrowserFrameworkR2RToPackage"
Condition="'$(WasmEnableFrameworkR2R)' == 'true'"
DependsOnTargets="_CrossgenBrowserFrameworkR2R"
BeforeTargets="AddFrameworkFilesToPackage">
<ItemGroup>
<_WasmFrameworkR2ROutput Include="$(_WasmFrameworkR2RDir)*.wasm" />
<_WasmFrameworkR2ROutput Include="$(CoreCLRArtifactsPath)System.Private.CoreLib.wasm"
Condition="Exists('$(CoreCLRArtifactsPath)System.Private.CoreLib.wasm')" />
<LibrariesRuntimeFiles Include="@(_WasmFrameworkR2ROutput)" IsNative="true" NativeSubDirectory="r2r" />
<PlatformManifestFileEntry Include="@(_WasmFrameworkR2ROutput->'%(FileName)%(Extension)')" IsNative="true" />
</ItemGroup>
<!-- In-tree runtime-pack layout is assembled by binplace + libs.pretest (not the nupkg), so copy in explicitly. -->
<Copy Condition="'$(MicrosoftNetCoreAppRuntimePackNativeDir)' != '' and '@(_WasmFrameworkR2ROutput)' != ''"
SourceFiles="@(_WasmFrameworkR2ROutput)"
DestinationFolder="$([MSBuild]::NormalizeDirectory('$(MicrosoftNetCoreAppRuntimePackNativeDir)', 'r2r'))"
SkipUnchangedFiles="true" />
</Target>

<!--
Put the mibc file into tools and not into PgoData. Add it after GetFilesToPackage to ensure it isn't automatically classified.
Putting it in tools will also hide it from being part of the RuntimeList.xml.
Expand Down
9 changes: 9 additions & 0 deletions src/mono/browser/build/BrowserWasmApp.CoreCLR.targets
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,15 @@
<_WasmManagedAssemblies Include="@(WasmAssembliesToBundle->Distinct())" />
</ItemGroup>

<!-- With R2R the published .dll are webcil-in-wasm images MetadataLoadContext can't parse; scan the
trimmed IL (same closure crossgen used) instead. Gated on the linker dir only, because the nested
WasmNestedPublishApp build where this runs doesn't carry PublishReadyToRun. -->
<ItemGroup Condition="'$(IntermediateLinkDir)' != ''">
<_WasmManagedAssembliesR2RRemap Include="@(_WasmManagedAssemblies)" Condition="Exists('$(IntermediateLinkDir)%(FileName)%(Extension)')" />
<_WasmManagedAssemblies Remove="@(_WasmManagedAssembliesR2RRemap)" />
<_WasmManagedAssemblies Include="@(_WasmManagedAssembliesR2RRemap->'$(IntermediateLinkDir)%(FileName)%(Extension)')" />
</ItemGroup>

<!-- Locate System.Private.CoreLib in runtime pack if not already bundled -->
<PropertyGroup>
<_HasCoreLib Condition="'%(_WasmManagedAssemblies.FileName)%(_WasmManagedAssemblies.Extension)' == 'System.Private.CoreLib.dll'">true</_HasCoreLib>
Expand Down
9 changes: 9 additions & 0 deletions src/mono/browser/build/WasmApp.InTree.props
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@
<UseMonoRuntime>true</UseMonoRuntime>
</PropertyGroup>

<!-- In-tree R2R uses the in-build crossgen2. These two hooks must be props-time (property defaults live
in the CoreCLR .targets); both are inert unless PublishReadyToRun. See PR.md. -->
<PropertyGroup Condition="'$(RuntimeFlavor)' == 'CoreCLR' and '$(TargetOS)' == 'browser'">
<AfterMicrosoftNETSdkTargets Condition="'$(Crossgen2SdkOverrideTargetsPath)' != '' and Exists('$(Crossgen2SdkOverrideTargetsPath)')">$(AfterMicrosoftNETSdkTargets);$(Crossgen2SdkOverrideTargetsPath)</AfterMicrosoftNETSdkTargets>
<AfterMicrosoftNETSdkTargets>$(AfterMicrosoftNETSdkTargets);$(MSBuildThisFileDirectory)WasmApp.ReadyToRun.targets</AfterMicrosoftNETSdkTargets>
</PropertyGroup>
<Import Project="$(Crossgen2SdkOverridePropsPath)"
Condition="'$(RuntimeFlavor)' == 'CoreCLR' and '$(TargetOS)' == 'browser' and '$(Crossgen2SdkOverridePropsPath)' != '' and Exists('$(Crossgen2SdkOverridePropsPath)')" />

<PropertyGroup Condition="'$(IsTestProject)' == 'true' or '$(IsOutputTypeLibrary)' == 'true'">
<OutputType>library</OutputType>
</PropertyGroup>
Expand Down
18 changes: 18 additions & 0 deletions src/mono/browser/build/WasmApp.ReadyToRun.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project>
<!-- In-tree only: override ResolveReadyToRunCompilers to use the in-build crossgen2 (mirrors
AppleBuild.ReadyToRun.targets). Imported after the SDK targets so it wins. -->
<Target Name="ResolveReadyToRunCompilers"
Condition="'$(PublishReadyToRun)' == 'true'"
DependsOnTargets="$(ResolveReadyToRunCompilersDependsOn)">
<PropertyGroup>
<Crossgen2Path>$([MSBuild]::NormalizePath('$(Crossgen2InBuildDir)', 'crossgen2$(ExeSuffix)'))</Crossgen2Path>
</PropertyGroup>

<ItemGroup>
<Crossgen2Tool Include="$(Crossgen2Path)"
TargetArch="$(TargetArchitecture)"
TargetOS="$(TargetOS)"
PerfmapFormatVersion="$(PublishReadyToRunPerfmapFormatVersion)"/>
</ItemGroup>
</Target>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<!--
***********************************************************************************************
Microsoft.NET.Sdk.WebAssembly.Browser.CoreCLR.targets

ReadyToRun for CoreCLR browser-wasm. See PR.md / dotnet/runtime#121257 for the full design.
MUST be a .targets (not .props) and import on '== false' (not '!= true'): the SDK defaults
UseMonoRuntime=true and imports .props before the body sets it false, and Mono apps leave it unset.

Copyright (c) .NET Foundation. All rights reserved.
***********************************************************************************************
-->
<Project>

<!-- Default R2R on for CoreCLR browser (mirrors AppleBuild.props); targets-time is early enough (consumed by later targets). -->
<PropertyGroup>
<PublishReadyToRun Condition="'$(PublishReadyToRun)' == ''">true</PublishReadyToRun>
</PropertyGroup>

<PropertyGroup Condition="'$(PublishReadyToRun)' == 'true'">
<!-- Force over SDK defaults: net11+ defaults ContainerFormat=pe (unloadable on wasm); staging requires non-composite. -->
<PublishReadyToRunContainerFormat Condition="'$(PublishReadyToRunContainerFormat)' != 'wasm'">wasm</PublishReadyToRunContainerFormat>
<PublishReadyToRunComposite Condition="'$(PublishReadyToRunComposite)' != 'false'">false</PublishReadyToRunComposite>
<!-- NYI/SIMD methods crossgen2 can't emit into R2R fall back to the runtime JIT. -->
<PublishReadyToRunCrossgen2ExtraArgs>$(PublishReadyToRunCrossgen2ExtraArgs);--codegenopt:JitWasmNyiToR2RUnsupported=1;--codegenopt:JitWasmSimdNyiToR2RUnsupported=1</PublishReadyToRunCrossgen2ExtraArgs>
Comment on lines +19 to +24
</PropertyGroup>

<!-- Probe dirs for ConvertDllsToWebcil, separate for build vs publish (see PR.md):
build always uses the untrimmed pack images (a build is never trimmed; PublishTrimmed in the csproj
only configures publish); trimmed publish must use per-app crossgen output. _WasmPackR2RDir is set
here (target time) because _RuntimePackNativeDir is only set by _ResolveGlobalizationConfiguration. -->
<Target Name="_WasmCoreClrSelectR2RDirectories"
DependsOnTargets="_ResolveWasmConfiguration">
<PropertyGroup>
<_WasmPackR2RDir Condition="'$(_WasmPackR2RDir)' == '' and '$(_RuntimePackNativeDir)' != ''">$([MSBuild]::NormalizeDirectory('$(_RuntimePackNativeDir)', 'r2r'))</_WasmPackR2RDir>
</PropertyGroup>
<PropertyGroup Condition="'$(PublishReadyToRun)' == 'true'">
<_WasmPublishR2RDir Condition="'$(_WasmPublishR2RDir)' == ''">$([MSBuild]::NormalizeDirectory('$(IntermediateOutputPath)', 'R2R'))</_WasmPublishR2RDir>
<_WasmBuildPrebuiltR2RDirectories>$(_WasmPackR2RDir)</_WasmBuildPrebuiltR2RDirectories>
<_WasmPublishPrebuiltR2RDirectories Condition="'$(PublishTrimmed)' == 'true'">$(_WasmPublishR2RDir)</_WasmPublishPrebuiltR2RDirectories>
<_WasmPublishPrebuiltR2RDirectories Condition="'$(PublishTrimmed)' != 'true'">$(_WasmPackR2RDir)</_WasmPublishPrebuiltR2RDirectories>
</PropertyGroup>
</Target>

<!-- Prune raw pack R2R images (native/r2r/*.wasm) from build copy-local so the 90 MB closure never lands
loose in bin/; the managed .dll stays and ConvertDllsToWebcil stages the image. Unconditional (staging gated separately). -->
<Target Name="_WasmCoreClrPrunePackR2RFromBuild"
Condition="'$(_WasmEnableWebcil)' == 'true'"
DependsOnTargets="_WasmCoreClrSelectR2RDirectories"
BeforeTargets="_ComputeWasmBuildCandidates">
<ItemGroup>
<ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)"
Condition="'%(Extension)' == '.wasm' and '$(_WasmPackR2RDir)' != '' and Exists('$(_WasmPackR2RDir)%(FileName).wasm')" />
</ItemGroup>
</Target>

<!-- Same prune for publish, before ProcessPublishFilesForWasm derives _WasmResolvedFilesToPublish. -->
<Target Name="_WasmCoreClrPruneR2RFromPublish"
Condition="'$(_WasmEnableWebcil)' == 'true'"
DependsOnTargets="_WasmCoreClrSelectR2RDirectories"
BeforeTargets="ProcessPublishFilesForWasm">
<ItemGroup>
<ResolvedFileToPublish Remove="@(ResolvedFileToPublish)"
Condition="'%(Extension)' == '.wasm' and '$(_WasmPackR2RDir)' != '' and Exists('$(_WasmPackR2RDir)%(FileName).wasm')" />
</ItemGroup>
</Target>

<!-- Feed the trimmed IL closure into mainline R2R as the compile+reference set (see PR.md "SWA vs iOS").
On the Blazor/SWA route ILLink stamps PostprocessAssembly=true on its own collection, not on
ResolvedFileToPublish, so the mainline compile list is empty and crossgen2 never runs. -->
<Target Name="_WasmFeedReadyToRunCompileList"
Condition="'$(PublishReadyToRun)' == 'true' and '$(PublishTrimmed)' == 'true' and '$(PublishReadyToRunComposite)' != 'true' and '$(IntermediateLinkDir)' != ''"
BeforeTargets="_PrepareForReadyToRunCompilation">
<ItemGroup>
<!-- Clear the stale base-SDK R2R mark on the untrimmed runtime-pack copy (e.g. CoreLib under native/)
so crossgen resolves against the trimmed IL supplied below; it stays for webcil output. -->
<ResolvedFileToPublish Update="@(ResolvedFileToPublish)" PostprocessAssembly="false"
Condition="'%(ResolvedFileToPublish.PostprocessAssembly)' == 'true' and Exists('$(IntermediateLinkDir)%(ResolvedFileToPublish.FileName).dll')" />
</ItemGroup>
<ItemGroup>
<_WasmReadyToRunCompileInput Include="$(IntermediateLinkDir)*.dll" />
<ResolvedFileToPublish Include="@(_WasmReadyToRunCompileInput)"
PostprocessAssembly="true"
RelativePath="%(FileName)%(Extension)"
CopyToPublishDirectory="PreserveNewest" />
</ItemGroup>
</Target>

<!-- Force crossgen (CreateReadyToRunImages) before ProcessPublishFilesForWasm: the latter runs
AfterTargets=ILLink, which a Blazor publish schedules ahead of R2R, so the images would ship too late. -->
<Target Name="_WasmEnsureReadyToRunBeforePublish"
Condition="'$(PublishReadyToRun)' == 'true' and '$(PublishReadyToRunComposite)' != 'true' and '$(WasmBuildingForNestedPublish)' != 'true'"
DependsOnTargets="CreateReadyToRunImages"
BeforeTargets="ProcessPublishFilesForWasm" />

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ Copyright (c) .NET Foundation. All rights reserved.
Inputs="@(_WasmDllBuildCandidates);$(MSBuildProjectFullPath);$(MSBuildThisFileFullPath);$(_WebAssemblySdkTasksAssembly)"
Outputs="@(_WasmDllBuildCandidates->'%(WebcilOutputPath)')">

<ConvertDllsToWebcil Candidates="@(_WasmDllBuildCandidates)" IntermediateOutputPath="$(_WasmBuildTmpWebcilPath)" OutputPath="$(_WasmBuildWebcilPath)" IsEnabled="$(_WasmEnableWebcil)" WebcilVersion="$(_WasmWebcilVersion)">
<ConvertDllsToWebcil Candidates="@(_WasmDllBuildCandidates)" IntermediateOutputPath="$(_WasmBuildTmpWebcilPath)" OutputPath="$(_WasmBuildWebcilPath)" IsEnabled="$(_WasmEnableWebcil)" WebcilVersion="$(_WasmWebcilVersion)" PrebuiltR2RDirectories="$(_WasmBuildPrebuiltR2RDirectories)">
<Output TaskParameter="FileWrites" ItemName="FileWrites" />
<Output TaskParameter="FileWrites" ItemName="_WasmConvertedWebcilOutputs" />
</ConvertDllsToWebcil>
Expand Down Expand Up @@ -1010,7 +1010,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<_WasmPublishTmpWebcilPath>$([MSBuild]::NormalizeDirectory($(IntermediateOutputPath), 'tmp-webcil', 'publish'))</_WasmPublishTmpWebcilPath>
</PropertyGroup>

<ConvertDllsToWebcil Candidates="@(_NewWasmPublishStaticWebAssets)" IntermediateOutputPath="$(_WasmPublishTmpWebcilPath)" OutputPath="$(_WasmPublishWebcilPath)" IsEnabled="$(_WasmEnableWebcil)" WebcilVersion="$(_WasmWebcilVersion)">
<ConvertDllsToWebcil Candidates="@(_NewWasmPublishStaticWebAssets)" IntermediateOutputPath="$(_WasmPublishTmpWebcilPath)" OutputPath="$(_WasmPublishWebcilPath)" IsEnabled="$(_WasmEnableWebcil)" WebcilVersion="$(_WasmWebcilVersion)" PrebuiltR2RDirectories="$(_WasmPublishPrebuiltR2RDirectories)">
<Output TaskParameter="WebcilCandidates" ItemName="_NewWebcilPublishStaticWebAssetsCandidates" />
<Output TaskParameter="FileWrites" ItemName="FileWrites" />
</ConvertDllsToWebcil>
Expand Down Expand Up @@ -1358,4 +1358,8 @@ Copyright (c) .NET Foundation. All rights reserved.
<TrimmerRootAssembly Include="$(AssemblyName)" RootMode="all" />
</ItemGroup>
</Target>

<!-- CoreCLR browser-wasm R2R, isolated from Mono. '== false' (not '!= true'): Mono apps leave UseMonoRuntime unset. -->
<Import Project="$(MSBuildThisFileDirectory)Microsoft.NET.Sdk.WebAssembly.Browser.CoreCLR.targets"
Condition="'$(UseMonoRuntime)' == 'false'" />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --dump-dependencies</_ExtraTrimmerArgs>

<!--
<PublishReadyToRun>true</PublishReadyToRun>
<RunAOTCompilation>true</RunAOTCompilation>
<WasmNativeDebugSymbols>true</WasmNativeDebugSymbols>
<WasmNativeStrip>false</WasmNativeStrip>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<GenerateRunScriptForSample Condition="'$(ArchiveTests)' == 'true'">true</GenerateRunScriptForSample>
<ExpectedExitCode>2</ExpectedExitCode>
<RunScriptCommand>$(ExecXHarnessVar) wasm test --app=. --engine=NodeJS --engine-arg=--stack-trace-limit=1000 --js-file=main.mjs --output-directory=$(XHarnessOutputVar) --expected-exit-code $(ExpectedExitCode)</RunScriptCommand>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>

<Target Name="RunSample" DependsOnTargets="RunSampleWithNode" />
Expand Down
Loading
Loading