Skip to content

Trim unused CoreCLR native components from dotnet-linker-tests build - #131666

Open
sbomer wants to merge 3 commits into
dotnet:mainfrom
sbomer:runtime-linker-test-perf
Open

Trim unused CoreCLR native components from dotnet-linker-tests build#131666
sbomer wants to merge 3 commits into
dotnet:mainfrom
sbomer:runtime-linker-test-perf

Conversation

@sbomer

@sbomer sbomer commented Jul 31, 2026

Copy link
Copy Markdown
Member

The Runtime_Release jobs in the dotnet-linker-tests pipeline build the clr subset. That expands to a list of CoreCLR subsets (eng/Subsets.props, DefaultCoreClrSubsets) which includes clr.native, and clr.native performs a full CoreCLR native build. That pulls in components the trimming and NativeAOT tests never use — most notably the cross-target alt-JITs and SuperPMI.

This PR narrows the subset list to what those tests actually need, and fixes a Windows/Unix asymmetry in the JIT install rules that blocked doing so.

1. src/coreclr/jit/CMakeLists.txt — install the target-specific JIT into the jit component on Windows

crossgen2 and ILC don't load clrjit; they load the JIT named for the target they're compiling for, e.g. clrjit_win_x64_x64 when targeting win-x64.

On Unix that JIT is already installed into the jit component alongside clrjit:

if (CLR_CMAKE_TARGET_UNIX)
      ...
      install_clr(TARGETS clrjit_unix_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} DESTINATIONS . COMPONENT jit)
endif()

Windows had no equivalent rule, so there the target-specific JIT was only ever installed as part of alljits. Any Windows build that selects native components individually rather than doing a full native build therefore produces a crossgen2 that fails as soon as it runs:

EXEC : error : Dll was not found. [src\coreclr\crossgen-corelib.proj]
error MSB3073: ...crossgen2.exe ... System.Private.CoreLib.dll ... exited with code 1

This mirrors the existing Unix rule for Windows targets. Full native builds are unaffected, since alljits already installed these JITs — it only makes the jit component self-contained on Windows the way it already is on Unix.

2. eng/pipelines/runtime-linker-tests.yml — narrow the subset list

clr.native is replaced by clr.runtime + clr.nativeaotruntime (the runtime and nativeaot CMake components). src/coreclr/components.cmake shows runtime already depends on jit, iltools, debug and hosts, and with the fix above jit now also carries the JIT crossgen2/ILC need.

Dropped as a result:

  • alljits — the cross-target alt-JITs. On win-x64 only clrjit and clrjit_win_x64_x64 are now built; on linux-x64 only clrjit and clrjit_unix_x64_x64.
  • spmi — SuperPMI and its shims.
  • clr.packages — only produces the ILAsm/ILDAsm/TestHost/Sdk.IL nupkgs, referenced solely by eng/Publishing.props for official-build publishing. Packing them takes ~2.5s, so this is a cleanliness change, not a perf one.
  • clr.crossarchtools — redundant here: _BuildCrossComponents is already set whenever ClrRuntimeBuildSubsets is non-empty for CoreCLR, and the cross-tool build is gated on _BuildAnyCrossArch, which is false for native windows-x64/linux-x64. Verified that no cross-arch build directory is produced either way.

Measurements

Measured on CI, comparing build 1538104 (this PR) against 1534932 (a recent PR build of the unchanged pipeline):

ninja targets "Build product"
windows-x64 (critical path) 2646 → 1901 (−28.2%) 40.0m → 35.4m (−4.6m)
linux-x64 2837 → 2132 (−24.8%) 31.7m → 29.0m (−2.7m)
browser-wasm unaffected (builds mono) 26.0m → 26.7m

The windows-x64 job as a whole goes from 62.4m to 56.5m. Total build wall clock went from 75.0m to 68.0m, though that figure includes queue variance across runs — the "Build product" numbers are the reliable ones. linux-x64 saves time too but stays off the critical path.

Locally, isolating just the CoreCLR native build on linux-x64 at ninja -j 4 (the parallelism CI uses) gives 4m03s → 3m05s, i.e. −24%, consistent with the CI result.

Validation

Locally, from a clean tree with the narrowed subsets:

  • Trimming tests: 88 tests pass
  • NativeAOT test apps: 57 tests pass
  • Artifacts verified: libcoreclr.so, ilc, crossgen2, ilasm/ildasm, DAC/mscordbi and the aotsdk all still present; superpmi and the unused alt-JITs gone

On CI, all three dotnet-linker-tests jobs (windows-x64, linux-x64, browser-wasm) pass, including the trimming and NativeAOT test app steps, with no change in test counts or coverage.

Two unrelated failures show up on this PR and are not caused by it:

  • runtime (Build openbsd-x64 Debug CoreCLR_Bootstrapped) — fails with NETSDK1203 on every recent PR (sampled 6/6); the leg only passes on main because rolling builds run it as Release.
  • System.Net.Security.Tests.TlsSessionTests.SslStreamServer_RejectsClientCert_ClientObservesAlert on linux-arm64 — known flaky, tracked by Disable TLS resume in SslStreamServer_RejectsClientCert_ClientObservesAlert #131755 (44 hits in the last month).

Note

This content was created with assistance from AI.

The Runtime_Release jobs in the dotnet-linker-tests pipeline built the
`clr` subset, which expands to `clr.native` and therefore performs a full
CoreCLR native build. That includes several components the trimming and
NativeAOT tests never use, most notably the `alljits` component (six
cross-target alt-JITs) and `spmi` (SuperPMI and its shims).

Narrow the subset list to just the components the tests need. This drops
703 of 2837 ninja targets (~25%) from the CoreCLR native build. Measured
locally at `ninja -j 4`, matching the parallelism CI uses, the native
build goes from 4m03s to 3m05s (-24%).

Also drop two subsets that were pulled in by `clr` but are not needed:

* `clr.packages` only produces the ILAsm, ILDAsm, TestHost and Sdk.IL
  nupkgs, which are consumed solely by official-build publishing.
* `clr.crossarchtools` is redundant here: `_BuildCrossComponents` is
  already set whenever `ClrRuntimeBuildSubsets` is non-empty for CoreCLR,
  and the cross-tool build is gated on `_BuildAnyCrossArch`, which is
  false for native windows-x64 and linux-x64.

Validated from a clean tree with the narrowed subsets: the trimming tests
(88) and the NativeAOT test apps (57) all pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ce99ab84-7dd0-4307-8dbe-47d695b514de
Assisted-by: Copilot:claude-opus-5
@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.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib
See info in area-owners.md if you want to be subscribed.

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

Updates the runtime-linker-tests Azure Pipelines definition to build a narrower set of CoreCLR subsets for the Runtime_Release jobs, aiming to avoid building unused native components during trimming and NativeAOT test runs.

Changes:

  • Replaces -s clr+... with an explicit subset list centered on clr.runtime plus NativeAOT/tooling subsets.
  • Adds inline pipeline comments documenting why alljits and spmi are intentionally excluded.
Show a summary per file
File Description
eng/pipelines/runtime-linker-tests.yml Switches the CoreCLR build from clr to an explicit subset list intended to avoid building unused native components for linker/NativeAOT tests.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment thread eng/pipelines/runtime-linker-tests.yml Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 31, 2026 19:17

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.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 0 new

crossgen2 and ILC don't load clrjit; they load the JIT named for the
target they are compiling for, e.g. clrjit_win_x64_x64 when targeting
win-x64. On Unix that JIT is already installed into the `jit` component
alongside clrjit, so a build that requests only `-component runtime`
(which depends on `jit`) can run them. Windows had no equivalent rule, so
the target-specific JIT was only ever installed as part of `alljits`.

The result is that a Windows build which selects CoreCLR native
components individually, rather than doing a full native build, produces
a crossgen2 that fails at runtime with "Dll was not found" as soon as it
is invoked, for example while R2R compiling System.Private.CoreLib.

Mirror the existing Unix rule for Windows targets. Full native builds are
unaffected since `alljits` already installed these JITs; this only makes
the `jit` component self-contained on Windows the way it already is on
Unix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ce99ab84-7dd0-4307-8dbe-47d695b514de
Assisted-by: Copilot:claude-opus-5
Copilot AI review requested due to automatic review settings August 3, 2026 20:40

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.

Copilot's findings

Suppressed comments (1)

eng/pipelines/runtime-linker-tests.yml:119

  • The comment is slightly inaccurate: the clr subset expands to the full $(DefaultCoreClrSubsets) list (which includes clr.native among others), not to clr.native alone. Rewording avoids confusion for future maintainers reading the pipeline.
            # This replaces the previous `clr` subset (which expands to `clr.native` and builds every native component)
  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new

@azure-pipelines

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

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

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants