This will make the build slower, but will show why there’s a need to a rebuild.

Every time there’s a need to rebuild a project, you will see this kind of message:

In the Output window we can see what is being rebuilt and why.
Here for example, we see that we have a picture with “Copy always” attribute.

Let’s go over some common problems why this can happen.

Resource is set to “Copy always”

This is the example we just saw. “Copy always” means just what it says, and there’s never a good reason for that. There’s an option to Copy if newer instead of “Copy always”. We can find the resource file in the Solution Explore. Press F4 to see the properties and change the “Copy to output directory” field.

A reference with CopyLocal set to true, but unused in a VSIX project

I think this happens only with Visual Studio extensions (VSIX projects).

When referencing a project in an extension, there’s no need to Copy local since the VSIX file embeds everything in it. If it is set to True in the CopyLocal field (in reference properties) we might experience this problem. Simply setting CopyLocal to False solves this.

Circular dependency

Having a circular dependency in a .NET project is a bit difficult. VS prevents us from referencing a project directly. However, we can reference to a .dll file in the project’s output.

Suppose we have a project A that references project B.
In project B we can add a reference to A’s output file path(..A\bin\Debug\A.exe).

And here you go, a beautiful circular dependency. This will cause both projects to be rebuilt every time.

There’s no workaround here, we’ll have to get rid of the circular dependency.

These are the reasons I know of that cause this problem. If you encountered more reasons, please comment about them and I’ll add them to the post.

Now let’s see what we can do about that other issue.

When something did change, VS tends to build more projects than needed.

This is not just a feeling, MSBuild works in a specific way that sometimes does more work than it should. Here’s the problematic scenario:

Suppose we have a project A that references project B.
In project B we have a public function Foo() which project A uses.

If we change the signature of Foo() to Foo(int x), then A has to be built again. However, if we change the internal logic inside Foo(), there’s no reason for A to be built. Just B. But MSBuild will rebuild A anyway. (And all other projects referencing B)

I believe MSBuild simply works according to date modified. If A references B, and B was modified after A .dll was modified, then MSBuild will build A as well.

What can we do about it?

ReSharper Build supposedly solves this problem. And I believe it comes with ReSharper out of the box, no extra license required.

ReSharper Build has other cool features that will make your build much faster. I haven’t gotten around to trying it as I wanted a solution that will work even for team members who don’t have ReSharper installed, but since my manager swears by it, I thought it is worth a mention J

The silver lining here is that Microsoft are aware of this issue and claim they fixed it. It should be included in some future version of Visual Studio.

Summary

For me, those extra unnecessary build times are really annoying and I feel compelled to fix them. It’s easy to get lazy about making these improvements as no-one likes to mess about with MSBuild, but do it once and it will save you tons of time in the long run. On top of that, it’s really time saved for the entire team.