Skip to content

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

Closed

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 evaluation — ProcessFrameworkReferences 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

  1. dotnet-policy-service commented on Sep 7, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
    See info in area-owners.md if you want to be subscribed.

  2. added this to the 12.0.0 milestone on Sep 7, 2026
  3. removed
    untriagedNew issue has not been triaged by the area owner
    on Sep 7, 2026
  4. self-assigned this
    on Sep 7, 2026
  5. dotnet-policy-service commented on Sep 7, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @dotnet/runtime-infrastructure
    See info in area-owners.md if you want to be subscribed.

  6. added a commit that references this issue on Sep 14, 2026
    1c19e73
  7. added a commit that references this issue on Sep 18, 2026
    f80c85e
  8. locked and limited conversation to collaborators on Oct 14, 2026
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