Skip to content

Use WASM CoreLib when compiling crossgen2 WASM unit tests - #131024

Merged
jtschuster merged 25 commits into
dotnet:mainfrom
jtschuster:jtschuster-wasm-r2r-crossgen-test
Aug 24, 2026
Merged

Use WASM CoreLib when compiling crossgen2 WASM unit tests#131024
jtschuster merged 25 commits into
dotnet:mainfrom
jtschuster:jtschuster-wasm-r2r-crossgen-test

Conversation

@jtschuster

@jtschuster jtschuster commented Jul 19, 2026

Copy link
Copy Markdown
Member

ILCompiler.ReadyToRun.Tests uses the corelib for the build machine to compile for wasm. If crossgen ever takes a dependency on a wasm-only member being present in corelib, it could cause failures. The same issue is possible for tests targeting windows, arm, or ios-arm64.

Add a new clr.r2rtests subset to separate the tests from platform-independent clr.toolstests.

The ILCompiler.ReadyToRun.Tests now runs only tests that are compatible with the TargetArchitecture and TargetOS set in msbuild. Those properties are passed to the test via RuntimeConfiguration options. Unfortunately, this means that getting full coverage in a local run requires building libs for multiple targets and re-running the test for each target RID you want tests for.

The libraries and crossgen2 are now copied directly to the test bin directory.

Add jobs to runtime.yml to run r2rtests for each target we have tests for. Only the compiler input assets are platform-dependent - the runner itself compiles for AnyCPU and crossgen2 can cross-compile, so (most) tests can still run on linux-x64 after downloading the artifacts from previous builds (for iOS it builds the artifacts since there isn't a prior build that uploads the right artifacts). However, there are 2 regression tests which require --pdb to repro and is Windows only. For that reason, a Windows-targeting job runs on Windows pipeline machines.

We also could consider moving all but linux-x64 to the runtime-coreclr crossgen2 pipeline if these end up taking too long.

- Use CopyAllJitLibrariesToAotCompilerOutput=true instead of copying ourselves.
- Set crossgenDir based on crossgen2_inbuild.csproj output items
- Reorder properties and items to keep related items close to each other
Copilot AI lite review requested due to automatic review settings July 19, 2026 01:32
@github-actions github-actions Bot added the area-crossgen2-coreclr only use for closed issues label Jul 19, 2026
@jtschuster jtschuster changed the title Jtschuster wasm r2r crossgen test Use WASM CoreLib when compiling crossgen2 WASM unit tests Jul 19, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 5 pipeline(s).
11 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the ReadyToRun crossgen2 test runner and CI wiring so WASM-targeted R2R compilations can reference the browser-wasm runtime pack (including WASM System.Private.CoreLib) when it’s available, instead of always using the host runtime pack.

Changes:

  • Add browser-wasm runtime-pack path plumbing (and an opt-in “require wasm references” switch) to the ILCompiler.ReadyToRun.Tests test infrastructure.
  • Add a per-compilation target selector (TargetRid) so tests can request browser-wasm (or host-arm) crossgen2 args and reference sets.
  • Update pipeline to build + publish browser-wasm managed runtime-pack artifacts and download them into the CLR tools test job.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/installer/pkg/sfx/Microsoft.NETCore.App/Microsoft.NETCore.App.Runtime.CoreCLR.sfxproj Makes IncludeStaticLibrariesInPack overridable so CI can disable static libs for browser/wasi runtime-pack builds.
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/TestPaths.cs Simplifies path config and adds optional wasm runtime-pack locations + RequireWasmReferences switch.
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestRunner.cs Chooses host vs browser-wasm reference paths per compilation and passes reference paths into the resolver.
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestCaseCompiler.cs Changes Roslyn compilation reference setup to consume an explicit reference list.
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RResultChecker.cs Updates SimpleAssemblyResolver to resolve framework assemblies from a provided reference set rather than TestPaths.
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RDriver.cs Removes the dedicated “target arch arm” option in favor of TargetRid-driven args.
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCases/R2RTestSuites.cs Updates wasm and arm test cases to use TargetRid and tightens arm test gating.
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/ILCompiler.ReadyToRun.Tests.csproj Adds wasm runtime-pack discovery/config propagation and CI-oriented validation/warnings.
eng/pipelines/runtime.yml Builds browser-wasm libs for CLR tools tests, publishes them as artifacts, and downloads them into the tools test job.
Comments suppressed due to low confidence (1)

src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/TestPaths.cs:8

  • System.Text.RegularExpressions is no longer used in this file after removing the config-probing helpers; leaving it will either produce an unnecessary compiler warning (CS8019) or fail builds that treat warnings as errors.
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using Xunit.Abstractions;

Comment thread src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/TestPaths.cs Outdated
Copilot AI review requested due to automatic review settings July 20, 2026 16:07
@jtschuster jtschuster added area-ReadyToRun and removed area-crossgen2-coreclr only use for closed issues labels Jul 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (2)

src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestCaseCompiler.cs:77

  • R2RTestCaseCompiler now compiles test assemblies with OptimizationLevel.Debug, which changes the IL shape (and potentially crossgen2 output/validations) and seems unrelated to the PR’s wasm-reference selection. Unless there’s a specific reason, keeping Release here avoids altering baseline test behavior.
            new CSharpCompilationOptions(outputKind)
                .WithOptimizationLevel(OptimizationLevel.Debug)
                .WithAllowUnsafe(true)
                .WithNullableContextOptions(NullableContextOptions.Enable));

src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/ILCompiler.ReadyToRun.Tests.csproj:67

  • MSBuild Exists(...) checks should avoid hardcoding \ path separators. On non-Windows builds this can cause false negatives (and in this case, the error is raised very early). Using / (or NormalizeDirectory) keeps the check portable.
    <Error Condition="!Exists('$(CoreCLRArtifactsPath)\$(BuildArchitecture)\crossgen2')"
           Text="Crossgen2 inbuild publish directory '$(CoreCLRArtifactsPath)\$(BuildArchitecture)\crossgen2' does not exist. This is a build authoring error and should be generated in the test project build." />

Comment thread src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/TestPaths.cs Outdated
Copilot AI review requested due to automatic review settings July 20, 2026 21:05
@jtschuster
jtschuster marked this pull request as ready for review July 20, 2026 21:07
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 5 pipeline(s).
11 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/ILCompiler.ReadyToRun.Tests.csproj:67

  • The ValidatePathsExist target builds a path using backslashes (e.g. '$(CoreCLRArtifactsPath)$(BuildArchitecture)\crossgen2'). On non-Windows agents this can become a literal backslash in the path and cause a false failure even when the directory exists. Use forward slashes or NormalizeDirectory/NormalizePath to keep the Exists check cross-platform.
    <Error Condition="!Exists('$(CoreCLRArtifactsPath)\$(BuildArchitecture)\crossgen2')"
           Text="Crossgen2 inbuild publish directory '$(CoreCLRArtifactsPath)\$(BuildArchitecture)\crossgen2' does not exist. This is a build authoring error and should be generated in the test project build." />

Comment thread eng/pipelines/runtime.yml Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCasesRunner/R2RTestRunner.cs:352

  • BuildReferencePaths() enumerates the libraries directory every time it’s called (Directory.GetFiles), and the current runner calls it multiple times per test case (e.g., once for Roslyn compilation and again for validation). Caching the computed list avoids repeated filesystem enumeration and keeps behavior the same for a given test run.
    private static List<string> BuildReferencePaths()
    {
        string librariesDir = TestPaths.LibrariesDir;

        List<string> paths = [.. Directory.GetFiles(librariesDir, "*.dll")];
        Assert.True(
            paths.Exists(p => Path.GetFileName(p) == "System.Private.CoreLib.dll"),
            $"System.Private.CoreLib.dll not found in staged references: {librariesDir}");

        return paths;

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/ILCompiler.ReadyToRun.Tests.csproj:60

  • In SetupCopyCrossgen2CompilationAssets, the item is created from a transformed item list (the Include is already '%(OutputPath)'), so metadata like %(Crossgen2InbuildOutputItems.OutputPath) is not available when evaluating TargetPath. As written, GetFileName('%(Crossgen2InbuildOutputItems.OutputPath)') will likely evaluate to an empty string, causing files to be copied to an invalid/empty TargetPath (and potentially overwrite/collide). Use the new Content item's own metadata (%(Filename)%(Extension)) instead.
      <!-- Filename Metadata may differ from the filename of OutputPath. We want to copy the file using the actual filename of the output path. -->
      <Content Include="@(Crossgen2InbuildOutputItems->'%(OutputPath)')"
               CopyToOutputDirectory="PreserveNewest"
               TargetPath="crossgen2/$([System.IO.Path]::GetFileName('%(Crossgen2InbuildOutputItems.OutputPath)'))" />

src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/WasmArgumentLayoutTests.cs:168

  • CreateWasmContext hard-codes TargetOS.Browser, but the test is only gated on TargetArchitecture == "wasm". The build can legitimately be -os wasi -arch wasm (TargetOS='wasi' and TargetArchitecture='wasm' per eng/OSArch.props), in which case this test would run but build a Browser type system context, producing incorrect layouts/behavior for the actual target. Either gate on both OS+arch, or (simpler) derive the TargetOS enum from TestPaths.TargetOS when constructing TargetDetails.
        string coreLibPath = TestPaths.SystemPrivateCoreLibPath;
        Assert.True(File.Exists(coreLibPath), $"System.Private.CoreLib.dll not found at '{coreLibPath}'");

        InstructionSetSupport instructionSetSupport = new(default, default, TargetArchitecture.Wasm32);
        TargetDetails target = new(TargetArchitecture.Wasm32, TargetOS.Browser, TargetAbi.NativeAot, instructionSetSupport.GetVectorTSimdVector());

Copilot AI review requested due to automatic review settings August 21, 2026 16:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

@jtschuster

Copy link
Copy Markdown
Member Author

/ba-g unrelated timeout

@jtschuster
jtschuster merged commit 1d3f074 into dotnet:main Aug 24, 2026
184 of 186 checks passed
@github-project-automation github-project-automation Bot moved this to Done in AppModel Aug 24, 2026
@pavelsavara pavelsavara added the arch-wasm WebAssembly architecture label Aug 24, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

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

Labels

arch-wasm WebAssembly architecture area-ReadyToRun

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants