Introduction To MSBuild


Click here to change the theme.

A Project element is the root element of a MSBuild project file. The most simplest sample would be:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>
    

Properties

MSBuild properties are simply a collection of key-value pairs consisting of names and values. Static properties are always in a PropertyGroup element. Dynamic properties are explained later. There can be multiple PropertyGroup elements but all properties are placed together in one collection. Except a PropertyGroup element can have a Condition attribute. In a PropertyGroup element, the XML tag name of the elements in it is the name of the property and the value of the property is value in the element.

A simple sample of a PropertyGroup element is:

<PropertyGroup>
  <SchemaVersion>2.0</SchemaVersion>
  <OutputType>Library</OutputType>
  <AppDesignerFolder>Properties</AppDesignerFolder>
  <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
  <UseIISExpress>false</UseIISExpress>
</PropertyGroup>
    

The preceding PropertyGroup has properties with the names SchemaVersion, OutputType, AppDesignerFolder, TargetFrameworkVersion and UseIISExpress.

Tasks and Targets

Tasks and Targets specify what to do. Tasks are contained in Targets. Targets consist of one (or zero) or more Tasks. MSBuild installs many tasks, including Csc, Vsc, AspNetCompiler and Message.  The Csc task executes the C# compiler. The Vsc task executes the VB .Net compiler. The AspNetCompiler task precompiles ASP.NET applications. The Message task shows messages in the output window during a build. There are very many more tasks.

Items

Items are an ordered list of values. Items are specified in ItemGroup elements. The item names are specified as subelements of ItemGroup elements. An "Include" attribute specifies the list of values. An entire list can be included in a single Include attribute or the list can be spread across ItemGroup elements or subelements of the ItemGroup element. Each value in the list of values is normally a file.

Items are either static or dynamic. Static items exist in the project and dynamic items exist in targets.

Targets

This article provides a very simple sample of targets in a Visual Studio 2010 project file. An over-simplified explanation of what a taget in a project is is that a target is something to do. The sample project in this article will do nothing except show messages when the project is built, rebuilt or cleaned. It is intended to show a project file in a very fundamental manner. I also explain a few tricks to help understand and work with project files. This article was written using Visual Studio 2010 and other versions of Visual Studio will vary.

I will begin with an introduction to projects and builds. The most fundamental explanation of projects is that a project specifies the source code file(s) of a program and the associated parameters (normaly compiler options) for processing (usually by a compiler) the program into something that can be used (usually an executable program). The action of processing a program into something that can be used is often called a "build", as in building the project. A build therefore is normally the action of compiling a specified list of source code files into an executable file. The word "target" implies items to be processed, but in Visual Studio (actually it is MSBuild; more about that later) a target is some processing to be done to items.

I assume you know what a build in Visual Studio is. Visual Studio 2010 uses the .Net "MSBuild" tool to do the build. MSBuild is provided with .Net, not Visual Studio; in other words, MSBuild is installed with .Net and MSBuild is available whether Visual Studio is installed or not. MSBuild is a command-line tool but Visual Studio provides such a great GUI interface to MSBuild that we usually are not aware of the use of MSBuild.

The extension for a project files is either "csproj" (for C#), "vbproj" (for VB .Net) or "vcxproj" (for C++). Note that solutions are not projects; solutions consist of one or more projects and solution files have the file extension "sln". Project files are XML files. When you use "File" | "New" | "Project..." in Visual Studio, a project file is usually created. A complete project file, as generated by Visual Studio, is quite complex. You will not understand them after reading this article, but this article is a very small beginning.

Creating a project file from scratch

I assume you are familiar with the Solution Explorer.

Begin by creating an empty solution. Do that from the Visual Studio 2010 menu using "File" | "New" | "Project...". Then in the "New Project" window in the left side are "Installed Templates". Expand the "Other Project Types" node then select the "Visual Studio Solutions" node. The middle pane shows the templates in the selected node; there will probably be only one template, which is "Blank Solution". If there is more than one template then ensure that "Blank Solution" is selected. Then give the solution a name. Your "New Project" window should look someting like:

[NewProject]

Then in the Solution Explorer right-click on the solution then select "Add" | "New Item..." (not "New Project..."). Then select "XML File" and enter a name for the file. Be sure to use "csproj" (not "xml") for the extension. Add the following lines:

<Project ToolsVersion="4.0"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
</Project>

Save the file and close the window (the edit window only; no need to close Visual Studio). Then return to the Solution Explorer and right-click on the solution and select "Add" | "Existing Project...". Select the project file as in:

Build the project. You will of course get an error; it will say "error MSB4040: There is no target in the project.". So return to the Solution Explorer and right-click on the solution and now select "Edit Project File". This is a way to open a project file in the Visual Studio editor with the solution open. The project will be "unloaded" and unavailable; in other words, you cannot do most anything else with a project when the project file is unloaded.

Add the following attribute to the Project element:

DefaultTargets="BuildTarget"

That will tell MSBuild to use the target named "BuildTarget" when we do a build. Next add the following subelements to the Project element:

<Target Name="BuildTarget">
    <Message Text="Build selected" Importance="high"/>
</Target> 

 Then save the file and close the edit window. Then return to the Solution Explorer and right-click on the solution and select "Reload Project". Then build the project. You should get the message "Build selected" along with the output of the build. Now try to "Rebuild" the project and/or "Clean" the project (those are two separate commands). If you are unfamiliar with rebuilding and/or cleaning a project, then just look in the project menu; the same place as where the "Build" command is. When you do the rebuild or clean, it will say that the target does not exist. We will now add two more Targets for those. So return to the Solution Explorer and edit the project file again. Then add the following two targets:

<Target Name="Rebuild">
    <Message Text="Rebuild selected" Importance="high"/> 
</Target>
<Target Name="Clean">
    <Message Text="Clean selected" Importance="high"/>
</Target>

Save the file and close the window. Then reload the project. Now when you rebuild or clean the project you will get the relevant message.

Using MSBuild from the command line

Since MSBuild is a command-line tool, it is possible to execute it from a command liine. If you open a command prompt without setting the path for Visual Studio and .Net tools then MSBuild will not be found. You can however right-click on the project in the Solution Explorer and then select "Open Command Prompt". A command prompt window will be opened with the path already set for use of MSBuild and the current directory will be the project directory. If you issue the command "MSBuild" without parameters then MSBuild will use default options for the solution in the current directory. Therefore if you just issue the command "MSBuild" then it will build the project. The outpur will look something like the following:

I will in the future write additional articles about project files and MSBuild.