Skip to content

[wasm][coreCLR] Out-of-repo relink cannot find crossgen2; acquire it through the SDK #133353

Description

@radekdoulik

Problem

Out of the repo, a wasm CoreCLR native relink cannot find crossgen2.

#131877 arranged for the wasm-tools workload to carry the crossgen2 pack, but made that change in src/mono/nuget/…Mono.Toolchain.Current.Manifest/, which per @akoeplinger is only used for testing. The manifest that ships is hand-authored in dotnet/sdk and never got the entry, so $(Crossgen2ToolPath) is never set and the relink fails with its own "install the wasm-tools workload" error — which installing the workload does not fix.

In-repo builds are unaffected: they resolve crossgen2 from $(Crossgen2InBuildDir), earlier in the same fallback chain.

Fix

dotnet/sdk#56119 added RequiresCrossgen2Pack, letting a build acquire the pack without PublishReadyToRun. Adopting it closes the gap with no manifest change in either repo.

  1. Set RequiresCrossgen2Pack in Microsoft.NET.Sdk.WebAssembly.Browser.CoreCLR.targets. It must be set during evaluationProcessFrameworkReferences runs BeforeTargets="…CollectPackageDownloads", so $(WasmBuildNative) cannot be the gate.

  2. Consume @(Crossgen2Tool) in BrowserWasmApp.CoreCLR.targets and WasiApp.CoreCLR.targets, as the last entry in the fallback chain.

  3. Remove the workload plumbing: the Microsoft.NETCore.App.Crossgen2.${NetVersion} entries in runtime's WorkloadManifest.json.in, the matching import in WorkloadManifest.targets.in, src/installer/pkg/sfx/Microsoft.NETCore.App/Crossgen2/Sdk.props, and the FilesToPackage line for it in Microsoft.NETCore.App.Crossgen2.props. Nothing to remove in dotnet/sdk. Also recheck whether eng/Subsets.props:772 (BuildCrossgen2HostPackForWorkloadTesting) is still needed.

  4. wasi, if wanted: wasi-experimental extends microsoft-net-runtime-mono-tooling, not wasm-tools, so it never got the pack and out-of-repo wasi relink still needs $(PortableCallHelpersGeneratorPath) set by hand.

Sequencing

This is the order anticipated when the workload route went in — "I know this means you'd need to get a new SDK first so we might have to go with this approach first".

Steps 1–2 can land now: they are additive, and on an SDK without #56119 the workload route still wins. Step 3 waits for an SDK carrying #56119 to flow in (global.json currently pins 11.0.100-rc.1.26420.103); removing the entries earlier would break the out-of-repo Wasm.Build.Tests legs.

Note that while both routes exist the workload one wins, so the SDK route stays untested until step 3.

Notes on step 2

ResolveReadyToRunCompilers errors rather than reporting nothing when no pack was resolved, and derives the path as <pack>/tools/crossgen2, which the flat $(Crossgen2InBuildDir) layout does not match — so the call has to be skipped when anything else already supplies a path. It also needs its own target, because CallTarget's item output is not visible to the calling target; and the guard cannot be hoisted to evaluation, because $(Crossgen2InBuildDir) comes from eng/liveBuilds.targets, imported after these files (same hazard as src/tests/Common/CLRTest.WasmCorerun.targets:109).

<Target Name="_CoreCLRResolvePortableCallHelpersGenerator"
        BeforeTargets="_CoreCLRGenerateManagedToNative"
        DependsOnTargets="ResolveFrameworkReferences">
  <CallTarget Targets="ResolveReadyToRunCompilers"
              Condition="'$(PortableCallHelpersGeneratorPath)' == '' and '$(Crossgen2InBuildDir)' == '' and '$(Crossgen2ToolPath)' == ''" />
</Target>

Alternative

Mirroring the #131877 manifest change into dotnet/sdk would also close the gap without waiting for a flow, but keeps the pack in the workload (~12.5 MB for everyone who installs wasm-tools) and leaves the entry to be maintained in two repos and removed from both later.

Note

This issue was drafted with GitHub Copilot.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions