From 5d6023a4847f5e76087612e8f245ea4cd486253c Mon Sep 17 00:00:00 2001 From: Sergey Tepliakov Date: Tue, 14 Apr 2026 05:55:35 -0700 Subject: [PATCH] Make CollectDeclaredReferences target incremental Add Inputs/Outputs to the CollectDeclaredReferences target so MSBuild can skip it on incremental builds when project file and assets file haven't changed. Two changes were needed: 1. Target Inputs/Outputs: Use \ for the Outputs path instead of GetFullPath(), since GetFullPath() resolves relative to the process working directory rather than the project directory. 2. Touch output file on unchanged content: SaveDeclaredReferences() has a write-only-if-different optimization that prevents updating the file timestamp when content is identical. This causes MSBuild to always consider the target out of date. Now we touch the file timestamp even when content is unchanged. Tested on a 305-project build (NeMo/Hardware in Azure-Compute-Move): - Before: CollectDeclaredReferences 26.8s (305 executions, 0 skipped) - After: CollectDeclaredReferences 0s (305 skipped) --- src/Package/build/ReferenceTrimmer.targets | 6 +++++- src/Tasks/CollectDeclaredReferencesTask.cs | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Package/build/ReferenceTrimmer.targets b/src/Package/build/ReferenceTrimmer.targets index a533591..3f970f3 100644 --- a/src/Package/build/ReferenceTrimmer.targets +++ b/src/Package/build/ReferenceTrimmer.targets @@ -9,7 +9,11 @@ - + <_ReferenceTrimmerDeclaredReferencesFile>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)_ReferenceTrimmer_DeclaredReferences.tsv')) <_ReferenceTrimmerUsedReferencesFile>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)_ReferenceTrimmer_UsedReferences.log')) diff --git a/src/Tasks/CollectDeclaredReferencesTask.cs b/src/Tasks/CollectDeclaredReferencesTask.cs index 00e3c6a..4d201d8 100644 --- a/src/Tasks/CollectDeclaredReferencesTask.cs +++ b/src/Tasks/CollectDeclaredReferencesTask.cs @@ -506,6 +506,9 @@ private static void SaveDeclaredReferences(IReadOnlyList decl string existing = File.ReadAllText(filePath); if (string.Equals(existing, newContent, StringComparison.OrdinalIgnoreCase)) { + // Touch the file so that MSBuild's Inputs/Outputs incrementality check + // sees a fresh timestamp and can skip the target on subsequent builds. + File.SetLastWriteTimeUtc(filePath, DateTime.UtcNow); return; } }