Skip to content

Make CollectDeclaredReferences support incremental builds#139

Merged
dfederm merged 1 commit intomainfrom
dfederm/incremental-collect-declared-refs
Apr 24, 2026
Merged

Make CollectDeclaredReferences support incremental builds#139
dfederm merged 1 commit intomainfrom
dfederm/incremental-collect-declared-refs

Conversation

@dfederm
Copy link
Copy Markdown
Owner

@dfederm dfederm commented Apr 24, 2026

Summary

Splits CollectDeclaredReferences into a multi-target pipeline with proper MSBuild Inputs/Outputs so the target can be skipped when nothing has changed.

Design

Four-target pipeline:

  1. _PrepareCollectDeclaredReferences (always runs) — computes properties, filters item groups, hashes non-file inputs (Reference names, PackageReference IDs, IgnorePackageBuildFiles, TFM, RID, etc.) into a cache file via Hash + WriteLinesToFile WriteOnlyWhenDifferent. Builds _CollectDeclaredReferencesInputs from file-based inputs (assets file, resolved references) plus the cache file.

  2. CollectDeclaredReferences (incremental) — runs the task, always writes the raw .tsv output.

  3. _StabilizeCollectDeclaredReferences (incremental) — copies raw to stable .tsv via ReadLinesFromFile + WriteLinesToFile WriteOnlyWhenDifferent. The stable file is passed to the compiler as AdditionalFiles, so CoreCompile only re-runs when content actually differs. This follows the pattern Rainer Sigwald described for ref assemblies.

  4. _EmbedReferenceTrimmerDiagnosticsInBinlog — embeds the raw .tsv in binlog after CoreCompile.

Incremental test results

Scenario CollectDeclaredReferences CoreCompile
First build RAN RAN
No-change rebuild SKIPPED SKIPPED
Touch .csproj (no semantic change) SKIPPED RAN (has own inputs)
Add PackageReference RAN RAN
Change TargetFramework RAN RAN
Source-only change SKIPPED RAN
Delete stable file (recovery) SKIPPED (raw ok) RAN

Additional cleanups

  • Removed unused MSBuildProjectFile task property
  • Simplified SaveDeclaredReferences to write directly via StreamWriter

Supersedes #136 with a more complete approach.

Split the single CollectDeclaredReferences target into a pipeline of four
targets to enable MSBuild Inputs/Outputs incremental skip:

1. _PrepareCollectDeclaredReferences (always runs) — computes properties,
   filters item groups, hashes non-file inputs (item groups, properties)
   into a cache file via Hash + WriteLinesToFile WriteOnlyWhenDifferent,
   builds _CollectDeclaredReferencesInputs, registers AdditionalFiles.

2. CollectDeclaredReferences (incremental via Inputs/Outputs) — runs the
   task which always writes the raw .tsv output.

3. _StabilizeCollectDeclaredReferences (incremental) — copies the raw .tsv
   to a stable .tsv via ReadLinesFromFile + WriteLinesToFile with
   WriteOnlyWhenDifferent. The stable file is what the compiler sees as
   AdditionalFiles, so CoreCompile only re-runs when content actually
   changes (not on timestamp-only changes).

4. _EmbedReferenceTrimmerDiagnosticsInBinlog (AfterTargets=CoreCompile) —
   embeds the raw .tsv in binlog.

Additional cleanups:
- Remove unused MSBuildProjectFile task property
- Simplify SaveDeclaredReferences to write directly via StreamWriter

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dfederm dfederm merged commit 26252d7 into main Apr 24, 2026
2 checks passed
@dfederm dfederm deleted the dfederm/incremental-collect-declared-refs branch April 24, 2026 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant