I set up the MSBuild project, so the default target is a new target, named just like "BuildWithExternalReference". This new goal names two other goals; the first is a custom target called "BuildExternalReference", which creates a DLL using an external tool. The DLL that is built is a reference for the main project, which is built using the usual Build target. I am setting the Inputs and Outputs attributes for the 'BuildExternalReference' target, so the inputs refer to the source files, and the outputs refer to the resulting DLL.
In Visual Studio 2012 and Visual Studio 2010, the assembly works correctly on the first call. However, in subsequent builds, if I change the external source files (referenced by the Attaching Inputs attribute "BuildExternalReference"), Visual Studio 2012 simply reports "Build: 0 successful, 0 failed, 1 updated, 0 skipped." Visual Studio 2010 continues to work fine. In addition, creating MSBuild.exe from the command line works fine.
I know that the build system in Visual Studio 2012 has changed, but I cannot find information about the changes in how incremental builds are performed.
Has anything changed in Visual Studio 2012 to cause incremental edits to change?
Here's the clipped version of the csproj file I'm using:
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" DefaultTargets="BuildWithExternalTool" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <ExternalSourceFiles Include="..\ExternalSourceFiles\\*\*.cs" /> <ExternalDll Include="..\ExternalSource\External.dll" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Target Name="BuildExternalTool" Inputs="@(ExternalSourceFiles);" Outputs="@(ExternalDll)"> <Exec Command="C:\External\Path\To\Tool.exe" /> </Target> <Target Name="BuildWithExternalTool"> <CallTarget Targets="BuildExternalTool" /> <CallTarget Targets="Build" /> </Target> </Project>
Update November 1, 2012
Here is a complete self-sufficient example that reproduces the problem:
https://skydrive.live.com/redir?resid=EA1DD6ACA92F9EFF!155&authkey=!ANhuqF_rrCgxpLE
This is a single project solution. The MSBuildIssueExample \ MSBuildIssueExample.csproj file has been configured so that there is a default target. This default target invokes the custom target (called "ExternalTool"), and then the default target assembly.
The ExternalTool custom target object writes some messages to make sure that it works, and also copies the contents of the MSBuildIssueExample \ ExternalTool \ Input.txt file on top of the MSBuildIssueExample \ ExternalTool \ Output.txt file.
The Input.txt file represents the input for the ExternalTool object, and the Output.txt file represents the output.
To recreate the problem, follow these steps:
1) Open the solution in the specified version of Visual Studio
2) Build the solution once to make sure the outputs are updated relative to the inputs
3) Modify the MSBuildIssueExample \ ExternalTool \ Input.txt file so that its contents do not match Output.txt
4) Again again
When you go through this process in Visual Studio 2010, the ExternalTool object will be called again, and the Input.txt file will be copied through Output.txt.
When you go through this process in Visual Studio 2012, the ExternalTool target will not be called even if the inputs are newer than the outputs, and as a result, the contents of Input.txt will not be written to Output.txt.
However, if you are rebuilding (not just Build), then both versions of Visual Studio work as expected.