Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Visual Studio keep building files that have not changed?

I'm using Visual Studio Enterprise 2019, and I'm curious about something I've noticed for a long time but never asked because it's not breaking anything: when building a solution, the final message looks like:

========== Build: 37 succeeded, 0 failed, 168 up-to-date, 0 skipped ==========

My understanding is that VS will only build files that changed (directly or via a dependency). But that doesn't seem to be the case, here's what I get after running several builds back to back right after the first build mentioned above and without making any changes to any part of the solution:

========== Build: 15 succeeded, 0 failed, 190 up-to-date, 0 skipped ==========

========== Build: 5 succeeded, 0 failed, 200 up-to-date, 0 skipped ==========

========== Build: 16 succeeded, 0 failed, 189 up-to-date, 0 skipped ==========

========== Build: 5 succeeded, 0 failed, 200 up-to-date, 0 skipped ==========

========== Build: 22 succeeded, 0 failed, 183 up-to-date, 0 skipped ==========

....and so on.

But I don't remember ever getting:

========== Build: 0 succeeded, 0 failed, 205 up-to-date, 0 skipped ==========

Why?

Note: I have seen "0 succeeded" in smaller solutions, so it's not like it never happens

like image 775
Sam Avatar asked Nov 01 '25 04:11

Sam


1 Answers

Projects are MSBuild files. Either directly or implicitly MSBuild is trying to check inputs against outputs to determine if a target should be run.

On the highest verbosity level which is 'diagnostic', MSBuild will provide information on why a project is being built.

But, in no specific order, here are some common situations that will cause a project to always build:

  1. If a file in the project has the "Copy to Output Directory" property set to "Copy Always", the project will always build to fulfill the copy.
    • Use "Copy if newer" instead of "Copy Always".
    • In MSBuild this property is the CopyToOutputDirectory attribute and the values Always and PreserveNewest are "Copy Always" and "Copy if newer", respectively.
  2. In a C# project, the pre and post build steps/events offered in the GUI project settings will cause a project to always build. Similarly in a C++ project the PreBuildEvent, PreLinkEvent, and PostBuildEvent have the same issue.
    • These items don't provide for specifying outputs and MSBuild has to always build the project because without outputs it can't determine if the step is already satisfied.
    • These items just shell-out to run shell commands and most often the shell command is a copy command. The MSBuild Copy task can replace usages like this. The Copy task has implicit inputs and outputs and runs in-process. Other commands can be run via an Exec task.
  3. In a C++ project a CustomBuildStep that doesn't specify outputs will cause a project to always build.
    • The CustomBuildStep does supports specifying outputs, but if outputs are not specified the CustomBuildStep will always run.
  4. A file that is copied or otherwise injected that is treated as an output but whose timestamp is always older than the related inputs.
    • i.e. The inputs have changed since the timestamp of the output therefore the output must be 'produced'.
like image 178
Jonathan Dodds Avatar answered Nov 04 '25 02:11

Jonathan Dodds



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!