Check for stale coreroot files before running coreclr tests#125815
Merged
jtschuster merged 12 commits intodotnet:mainfrom Apr 1, 2026
Merged
Check for stale coreroot files before running coreclr tests#125815jtschuster merged 12 commits intodotnet:mainfrom
jtschuster merged 12 commits intodotnet:mainfrom
Conversation
Add a BeforeTargets="RunTests" target that compares timestamps of key CLR binaries (coreclr.dll, clrjit.dll, System.Private.CoreLib.dll) between the build output and Core_Root. When staleness is detected, it emits MSBuild warnings identifying the specific stale files and suggests running -generatelayoutonly to fix. Also checks crossgen2.exe and IL-CG2 done-flag staleness when running R2R tests (RunCrossGen2=1). The check is silent when everything is fresh, and is skipped in CI builds (ContinuousIntegrationBuild=true) or when explicitly opted out (SkipCoreRootFreshnessCheck=true). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ping targets Replace the single CheckCoreRootFreshness target that checked 3 hardcoded files (clrjit.dll, coreclr.dll, System.Private.CoreLib.dll) with a pair of targets that comprehensively check all files in Core_Root: - _ComputeCoreRootFileMappings: Enumerates files in Core_Root and reverse-maps each to its build-output source file using priority-based resolution (CoreCLR artifacts > libraries managed > libraries native). Handles the crossgen2-published/ -> crossgen2/ rename and all identity-mapped subdirectories (PDB, IL, R2RDump, etc.). - CheckCoreRootFreshness: Incremental target (Inputs/Outputs) that is skipped entirely when all files are current. When stale files exist, emits per-file warnings identifying which files are out of date and a summary with the remediation command. Never fails the build. - _CheckIlCg2CacheFreshness: Separated IL-CG2 R2R cache staleness into its own target since it must run independently of Core_Root file freshness (RunCrossGen2=1 only). Suppressible via /p:SkipCoreRootFreshnessCheck=true. Disabled on CI (ContinuousIntegrationBuild=true). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move CheckCoreRootFreshness and _CheckIlCg2CacheFreshness from BeforeTargets=RunTests to RunTests' DependsOnTargets chain. MSBuild runs DependsOnTargets before BeforeTargets, so the previous placement caused the freshness check to run AFTER test execution (and to be skipped entirely if tests failed). Now the check runs first. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
GenerateLayoutOnly only copies pre-built artifacts into Core_Root; it doesn't need NuGet package restore or the VS developer environment. Skip both to cut the wall-clock time roughly in half. - build.cmd: jump past init-vs-env.cmd when GenerateLayoutOnly is set - build.cmd/build.sh: set __SkipRestorePackages=1 in the arg handler Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…/coreroot-freshness-check
This reverts commit 47c1c24.
Move the RunTimeArtifactsIncludeFolders definitions, exclude lists, and CoreCLR artifact glob logic from Directory.Build.targets into a shared CoreRootArtifacts.targets file. Both CopyDependencyToCoreRoot (copy) and CheckCoreRootFreshness (staleness check) now import the same file, eliminating the duplicated subdirectory list. The shared target _ComputeCoreRootArtifactSources produces _CoreRootArtifactSource items with Identity=source path and TargetDir metadata. CopyDependencyToCoreRoot adds these to RunTimeDependencyCopyLocal alongside NuGet-resolved items. The freshness check uses them for forward mapping, with a reverse-mapping fallback for libraries files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Warning task used item batching via %(_IlCg2DoneFiles.Identity) in its Condition, which would emit one identical warning per done file. Compute stale done files first, then emit a single warning. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a pre-test MSBuild target to detect and warn about stale binaries in Core_Root (compared to local build outputs) to reduce time lost running tests with outdated bits. Also factors the CoreCLR-artifact-to-Core_Root mapping into a shared targets file so both Core_Root generation and the new freshness check use the same mapping.
Changes:
- Introduces a two-phase Core_Root freshness check (
_ComputeCoreRootFileMappings+ incrementalCheckCoreRootFreshness) that runs before tests and emits warnings when Core_Root files are older than build outputs. - Adds a separate staleness warning for IL-CG2 R2R cache “done” markers vs. the
crossgen2in Core_Root. - Refactors CoreCLR artifact source mapping logic into a new shared
CoreRootArtifacts.targetsand wires it into Core_Root copy logic.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/tests/Common/tests.targets | Adds Core_Root and IL-CG2 freshness warning targets and makes RunTests depend on them. |
| src/tests/Common/Directory.Build.targets | Refactors Core_Root copy inputs to use the shared CoreRootArtifacts mapping and ensures mapping computation runs. |
| src/tests/Common/CoreRootArtifacts.targets | New shared target file that computes _CoreRootArtifactSource item mappings used by both Core_Root copy and freshness checking. |
5 tasks
am11
approved these changes
Mar 20, 2026
jtschuster
commented
Mar 20, 2026
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Jackson Schuster <36744439+jtschuster@users.noreply.github.com>
- Remove duplicate import of CoreRootArtifacts.targets (already imported via Directory.Build.targets, avoids MSB4011) - Use %(CoreRootFile) metadata for _UnmappedRootFile Remove instead of reconstructing the path, which is more precise for subdirectory artifacts Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
build.proj imports tests.targets directly without going through Common/Directory.Build.targets, so _ComputeCoreRootArtifactSources would not be available for the freshness check targets. Re-add the import with an import guard property (_CoreRootArtifactsImported) so it's skipped when already imported via Directory.Build.targets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jkoritzinsky
approved these changes
Mar 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Copilot often forgets to run src/tests/build.[sh|cmd] when iterating on the runtime and running tests. It's gone through many long loops trying to debug an issue when it's just the test running with stale bits. Instead, add a target to ensure there are no stale files in coreroot before running tests, and warn if there are. The warning can be disabled with
SkipCoreRootFreshnessCheck.The input/output mapping is copied to a shared point from what was done with
src/tests/build.cmd -generatelayoutonly.