MSBuild in Visual Studio Part 12: Compiling Inside Visual Studio

We’ve touched briefly on how the Compile target is used by Visual Studio, but only on how it relates to Intellisense. Of course while Intellisense is nice, most people would like to actually compile a complete application using Visual Studio. If you’re reading this blog you likely already know that MSBuild is used for the build process. But what target gets called when? It depends on the menu item used to kick off the build.

The Build menu item invokes the default target specified by the <project> tag. Typically this is the Build target. The Rebuild menu item invokes the Rebuild target. The Clean menu item invokes the… wait for it… Clean target. So far so good. Things get a little more complicated for some of the other menu commands, however.

The Publish menu actually invokes the default target and a second target called PublishOnly. This was done by the clickonce team to ensure that a complete build happens before the application is published to the server, while still allowing someone to call PublishOnly from a command line build to, uh, only publish.

The Run Code Analysis menu item calls the Rebuild target, but first sets the global RunCodeAnalysis property to true. This will enable assorted targets and tasks in the build to have the code analysis tools execute.

In addition to running targets, Visual Studio sets two global properties before builds. The first is BuildingInsideVisualStudio, which is true when the build was started from within Visual Studio. The second, BuildingProject, is true only when the Build command was executed. We tried really hard not to have these special properties, since we wanted VS builds and command-line builds to be identical, but there were a few situations where we needed them. BuildingInsideVisualStudio is used to prevent project-to-project references from being built automatically by MSBuild. This is because Visual Studio still takes care of figuring out the order of project builds when the IDE does the build. BuildingProject is primarily used for performance optimizations when build is run at design-time rather than build-time. For example, the ResolveAssemblyReference task can get away with doing less work when it’s design-time, and we don’t have to generate PDBs and satellite assemblies.

One aspect of running builds from within Visual Studio that you may not realize is that people do it a lot. We see developers do the build-debug-edit-build-debug cycle over and over during the course of a programming session. Because it happens so often, it’s critical that we have a fast up-to-date check so we can see if it’s necessary to build before the debug session starts. MSBuild is responsible for this check, and we’re quite proud of the work we’ve done here to make it as zippy as possible.

There’s one oddity about this, however. There’s still one place in Visual Studio where the up-to-date check is done by Visual Studio logic, not MSBuild. Can you guess where it is used?

[ Author: Neil Enns ]