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 ]

Comments (8)

  1. Hi, how do I list out the under-the-hood build commands (cs, resgen, al, etc) that are generated when I do a build in VS .NET?

    Hope you can help me on this.  Very much thanks.

  2. Tuncay says:

    "..and we’re quite proud of the work we’ve done here to make it as zippy as possible."

    IMHO, you should be ashamed about the performance of up-to-date check. VS.NET and MSBuild are only good for small projects. If you are developing a small project then performance is acceptable but..

    If you are developing a big project, say 40+ assemblies involved and a web site then performance of MSBuild and VS.NET gets down miserably.

    If you really want to know how a "proud up-to-date check" be possible try Eclipse. The definition of "zippy" will change instantly in your mind.

  3. Neil,

    have been searching (without success) for a method of determining WHY (within Visual Studio) projects are getting re-compiled on a Build. As far as I can tell, no dependancies have been updated.

    These "extra" compiles are often bumping "simple" builds up to gigantic (30+ minute) builds.

    I have a thread on the forums, so an answer there would provide the most benefit.

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2377428&SiteID=1

  4. Gurpreet Singh Bakshi says:

    "Can you guess where it is used?"

    I couldn’t find out. Could you please advise as to where it’s used and how it can be modified? My solution has a bunch of dependency projects which are rebuilt no matter what. I believe the uptodate check is being ignored by VS.

    Please help

  5. mh says:

    Nooooooo. Please could you answer your last question, I read the WHOLE internet to find an answer and when I find your blog you know the answer but do not tell…

    What I want to achieve is a custom msbuild-based project that is not rebuilt every time. When a C++ project is up-to-date and you try to build it, you get just one line "Build: 0 succeeded, 0 failed, 1 up-to-date, 0 skipped" without msbuild even running (or so it seems).

    When I try the same thing with my custom project, all files are correctly detected as up-to-date by msbuild, so no real work is done, but VS still thinks the project as a whole is outdated and it says "Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped". The difference is that when you press F5, VS asks you whether you want to build the project since it is outdated.

  6. bm says:

    I would appreciate the answer too. I have a project for which I added a custom Target to copy files to a specific directory. However if I delete the files from the destination directory and Build again VS immediately reports the build as up-to-date when actually it needs run msbuild to copy the files.

  7. Martin Ba. _ says:

    +1:

    What I want to achieve is a custom msbuild-based project that is not rebuilt every time. When a C++ project is up-to-date and you try to build it, you get just one line "Build: 0 succeeded, 0 failed, 1 up-to-date, 0 skipped" without msbuild even running (or so it seems).

    When I try the same thing with my custom project, all files are correctly detected as up-to-date by msbuild, so no real work is done, but VS still thinks the project as a whole is outdated and it says "Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped". The difference is that when you press F5, VS asks you whether you want to build the project since it is outdated.