Fixing C++ projects that always rebuild

After upgrading to Visual Studio 2010, one of our C++ projects would always be built, even if none of its files changed. When setting MSBuild output verbosity to “Normal”, the Build output window would show:

1>------ Build started: Project: SomeLib, Configuration: Release Win32 ------ 
1>InitializeBuildStatus: 
1>  Creating ".\Release\SomeLib.unsuccessfulbuild" because "AlwaysCreate" was specified. 
...
1>Build succeeded. 
1> 
1>Time Elapsed 00:00:00.47 
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== 

This occurred even though none of the files in that project had changed.

This forum thread and Connect issue describe the problem and state that it’s usually caused by referencing a .h file in the project that doesn’t exist on disk; the build system in VS2010 then assumes the project is out-of- date and builds it. The forum thread references a blog post about enabling C++ project system logging in order to diagnose the problem, but it didn’t help me identify the missing file. Instead, I wrote the following script to parse the project file and check for missing files:

// set this to your project

string fileName = @"C:\Path\To\MyProject.vcxproj";

XDocument project = XDocument.Load(fileName);
XNamespace msbuild = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");

int present = 0, missing = 0;
string folder = Path.GetDirectoryName(fileName);
foreach (XElement elem in project.Root.Elements(msbuild + "ItemGroup").Elements(msbuild + "ClInclude"))
{
    string name = (string)elem.Attribute("Include");
    string itemPath = Path.Combine(folder, name);
    if (!File.Exists(itemPath))
    {
        Console.WriteLine(name);
        missing++;
    }
    else
    {
        present++;
    }
}

Console.WriteLine("{0} files present, {1} missing.", present, missing);

You could change “ClInclude” to “ClCompile” to look for missing C++ files (but this should already be a build error) or to “None” to find missing non-source files.

Posted by Bradley Grainger on December 06, 2010