Skip to content

Visual Studio Fast Up To Date build not working - CopyComplete marker is touched when no files are copied #6576

@Scottj1s

Description

@Scottj1s

Visual Studio Version: 16.10.2

Summary:
With Fast Up To Date builds enabled, a subsequent build should not invoke MSBuild if no inputs have changed.

Steps to Reproduce:

  1. Launch VS command prompt
  2. Clone https://github.com/microsoft/CsWinRT/ repo
  3. cd into 'src' and run build.cmd
  4. After a successful baseline build, run 'devenv cswinrt.sln'
  5. Enable verbose build diagnostics
    Tools|Options|Projects and Solutions|Build And Run
    Set "MSBuild project build output verbosity:" to Diagnostic
  6. Enable verbose Up To Date diagnostics
    Tools|Options|Projects and Solutions|SDK-Style Projects
    Up do Date Checks
    Check "Don't call MSBuild if a project appearst to be up to date."
    Set "Logging Level:" to Verbose
  7. Right-click the Projections\Test project node and run several builds

Expected Behavior:
After the first build, Fast Up To Date should detect that no inputs are newer than outputs and not invoke MSBuild

Actual Behavior:
MSBuild is invoked every time. Excerpt of the build spew for target "_CopyFilesMarkedCopyLocal" below indicates the cause. Even though the Copy task reports "Did not copy from file" for every file, the WinUI.csproj.CopyComplete marker is still touched, causing the dependent Test project to be reported as "not up to date" and triggering an MSBuild.

Root Cause:
The reason appears to be a bug in the Copy task implementation. DoCopyIfNecessary initializes success to true, and returns that value when it also reports "Did not copy from file...". Calls to DoCopyIfNecessary set a local copyComplete to true and based on that value, add an entry to destinationFilesSuccessfullyCopied and ultimately the output parameter CopiedFiles. The _CopyFilesMarkedCopyLocal target in Microsoft.Common.CurrentVersion.targets binds CopiedFiles to the item ReferencesCopiedInThisBuild, which is used to conditionally touch the CopyUpToDateMarker. So even if no files are copied, the marker is still touched.

Build Spew:
Target "_CopyFilesMarkedCopyLocal" in file "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets":
Set Property: CreateHardLinksForCopyLocalIfPossible=false
Set Property: CreateSymbolicLinksForCopyLocalIfPossible=false
Task "Copy"
Task Parameter:UseHardlinksIfPossible=False
Task Parameter:SkipUnchangedFiles=True
Task Parameter:
DestinationFiles=
bin\x64\Release\net5.0\Windows.dll
bin\x64\Release\net5.0\WinRT.Runtime.dll
bin\x64\Release\net5.0\cswinrt.pdb
bin\x64\Release\net5.0\WinRT.Runtime.pdb
bin\x64\Release\net5.0\Windows.pdb
Task Parameter:
SourceFiles=
d:\git\cswinrt2\src\Projections\Windows\bin\x64\Release\net5.0\Windows.dll
d:\git\cswinrt2\src\WinRT.Runtime\bin\Release\net5.0\WinRT.Runtime.dll
d:\git\cswinrt2\src_build\x64\Release\cswinrt\bin\cswinrt.pdb
d:\git\cswinrt2\src\WinRT.Runtime\bin\Release\net5.0\WinRT.Runtime.pdb
d:\git\cswinrt2\src\Projections\Windows\bin\x64\Release\net5.0\Windows.pdb
Task Parameter:OverwriteReadOnlyFiles=False
Task Parameter:UseSymboliclinksIfPossible=False
Did not copy from file "d:\git\cswinrt2\src\WinRT.Runtime\bin\Release\net5.0\WinRT.Runtime.dll" to file "bin\x64\Release\net5.0\WinRT.Runtime.dll" because the "SkipUnchangedFiles" parameter was set to "true" in the project and the files' sizes and timestamps match.
Did not copy from file "d:\git\cswinrt2\src_build\x64\Release\cswinrt\bin\cswinrt.pdb" to file "bin\x64\Release\net5.0\cswinrt.pdb" because the "SkipUnchangedFiles" parameter was set to "true" in the project and the files' sizes and timestamps match.
Did not copy from file "d:\git\cswinrt2\src\WinRT.Runtime\bin\Release\net5.0\WinRT.Runtime.pdb" to file "bin\x64\Release\net5.0\WinRT.Runtime.pdb" because the "SkipUnchangedFiles" parameter was set to "true" in the project and the files' sizes and timestamps match.
Did not copy from file "d:\git\cswinrt2\src\Projections\Windows\bin\x64\Release\net5.0\Windows.pdb" to file "bin\x64\Release\net5.0\Windows.pdb" because the "SkipUnchangedFiles" parameter was set to "true" in the project and the files' sizes and timestamps match.
Did not copy from file "d:\git\cswinrt2\src\Projections\Windows\bin\x64\Release\net5.0\Windows.dll" to file "bin\x64\Release\net5.0\Windows.dll" because the "SkipUnchangedFiles" parameter was set to "true" in the project and the files' sizes and timestamps match.
Output Item(s):
FileWritesShareable=
bin\x64\Release\net5.0\Windows.dll
bin\x64\Release\net5.0\WinRT.Runtime.dll
bin\x64\Release\net5.0\cswinrt.pdb
bin\x64\Release\net5.0\WinRT.Runtime.pdb
bin\x64\Release\net5.0\Windows.pdb
Output Item(s):
ReferencesCopiedInThisBuild=
bin\x64\Release\net5.0\Windows.dll
bin\x64\Release\net5.0\WinRT.Runtime.dll
bin\x64\Release\net5.0\cswinrt.pdb
bin\x64\Release\net5.0\WinRT.Runtime.pdb
bin\x64\Release\net5.0\Windows.pdb
Done executing task "Copy".
Task "Touch"
Task Parameter:AlwaysCreate=True
Task Parameter:Files=d:\git\cswinrt2\src\Projections\WinUI\obj\x64\Release\net5.0\WinUI.csproj.CopyComplete
Touching "d:\git\cswinrt2\src\Projections\WinUI\obj\x64\Release\net5.0\WinUI.csproj.CopyComplete".
Output Item(s): FileWrites=d:\git\cswinrt2\src\Projections\WinUI\obj\x64\Release\net5.0\WinUI.csproj.CopyComplete
Done executing task "Touch".
Done building target "_CopyFilesMarkedCopyLocal" in project "WinUI.csproj".

...

FastUpToDate: Latest write timestamp on input marker is 6/16/2021 10:12:36 AM on 'd:\git\cswinrt2\src\Projections\WinUI\obj\x64\Release\netstandard2.0\WinUI.csproj.CopyComplete'. (Test)
FastUpToDate: Write timestamp on output marker is 6/16/2021 10:11:52 AM on 'd:\git\cswinrt2\src\Projections\Test\obj\x64\Release\netstandard2.0\Test.csproj.CopyComplete'. (Test)
FastUpToDate: Input marker is newer than output marker, not up to date. (Test)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions