MSBuild does a good job of reporting build errors, but MSBuild can only report errors that the underlying Tasks report. Custom tasks add a lot of variation to quality of the error messages. Case in point is the following message, which popped up as a deadline loomed.
Build FAILED. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:05.85
The build failed, but there are no errors to report. Yup. It's strange messages like this that make me want to curse in German, but I don't know German, so I make the noises an angry Klingon might make after living in Berlin for 5 years.
I couldn't find any problems in the output until I set MSBuild for maximum verbosity (/verbosity:diagnostic, /v:diag for short), at which point I found this in the output:
Done building target "PrepareRdlFiles" in project "...". Target "RunRdlCompiler" in file "...": Building target "RunRdlCompiler" completely. Output file "obj\Debug\RdlCompile.compiled" does not exist. Using "RdlCompile" task from assembly "Microsoft.ReportViewer.Common ...". Task "RdlCompile" Done executing task "RdlCompile" -- FAILED. Done building target "RunRdlCompiler" in project "CareAlertsWeb.csproj" -- FAILED.
Someone had added .rdlc files to the project. These are "Client Report Definition" files - think of Reporting Services reports without a report server. Something was going wrong compiling the .rdlc files, but there still wasn't any information to determine what the problem was. Without knowing what else to do I started looking at the RdlCompile task with Reflector.
The RdlCompile task is interesting. The task doesn't compile files in the traditional sense (transform inputs into outputs). The task validates the report definition inside the .rdlc file. This step ensures we'll get compile time errors instead of runtime errors from the ReportViewer control if the report definition is invalid.
The assembly hosting RdlCompile referenced another assembly that was not on the build machine (Microsoft.ReportViewer.ProcessingObjectModel). Mysterious. Why this caused the task to fail without reporting a more specific error is also a mystery.
With all the assemblies were in place, the RdlCompile task finished with success. Running ReportViewer.exe installs all the required assemblies, you can find it in %Program Files%\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\ReportViewer.