MSBuild: The New Build System for Visual Studio 2005 and Longhorn

MSBuild: The New Build System for Visual Studio 2005 and Longhorn

  • Comments 8

MSBuild is the new build system in Visual Studio 2005. It has been built from the ground up in managed code, with scalability, performance and extensibility as core goals.

When designing MSBuild, the development team had several different customer audiences that they kept in mind:

  • The Developer - someone who writes and compiles code regularly;
  • The Build Developer - someone who implements the processes for the build environment;
  • The Build Lab Tech - the person responsible for kicking off and managing the build process, making sure that builds don't break and fixing them as necessary. Note that this person may well not have Visual Studio on their machine.
  • The Build Lab Manager - who needs to track progress of the project and the build success/fail status. This individual would also probably not be a VS user.

MSBuild is actually built into the operating system, rather than the development environment. This means you can build Visual Studio projects without VS installed; all you need is Windows (and .NET Framework 2.0 until Longhorn).

MSBuild is driven by project files, which are created either by Visual Studio (automatically) or by hand by a developer. These are XML files that describe the build process elements (targets: build, clean, rebuild etc. that each contain constituent tasks) and inputs (items and properties). The project file is ultimately fed into the MSBuild engine, which in turn then generates the output.

The XML input to MSBuild is of course strongly-typed; the schema ships with VS 2005 Beta 1 and is called msbuild.xsd: if you include the namespace definition in Visual Studio when editing with its inbuilt XML editor, you'll get full Intellisense when working with MSBuild project files.

You can write the entire build process from scratch, if you like: here's a sample build project that compiles a C# application:

<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
      <OutputPath>Bin\</OutputPath>
      <AssemblyName>MSBuildSample</AssemblyName>
   </PropertyGroup>
  
   <ItemGroup>
      <Compile Include="MSBuildSample.cs"></Compile>
      <Reference Include="System.dll"></Reference>
   </ItemGroup>
 
<Target Name="Build">
   <MakeDir Directories="$(OutputPath)"
            Condition="!Exists('$(OutputPath)')" />
   <Csc Sources="@(Compile)"
        References="@(Reference)"
        OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
   </Target>
</Project>

To make the process simpler, MSBuild reuses elements of the build process through the use of .targets files, which define a compile target which is the override for any defaults. For example, Microsoft.CSharp.targets defines how to build C# applications with MSBuild; a similar file exists for J# and VB in the .NET Framework 2.0 directory (as specified in the LIBPATH environment variable).

  • How difficult is it to configure VisualStudio 2005 to MSBuild on a remote machine (so that, for example, you can run VS2005 on an XP desktop but compile for Longhorn on a Longhorn box)?

    -Don
  • Your post hints that this might be possible by using .target files - is it possible to customise build rules so that (say) C++ files also get linted as part of the compile step?

    Would there be any way of differentiating between files it's possible to lint (standard C++) and those where it's not really practical (e.g. Managed C++ and presumably C++/CLI initially)? Currently we're using different file extensions to make this differentiation, but it might be useful if we could say something along the lines of "apply this rule in this folder; apply that rule in that folder".

    I've read quite a bit about MS Build but no-one (that I have seen) has quite covered that area.
  • Nice post Tim! :)

    To answer Don's question: how difficult is it to configure VS to build on a longhorn box.

    Assuming that you must develop on an XP machine and build also on a longhorn machine, the easiest way to do this would be to do your development as you would on XP/Whidbey. Then copy/checkout your sources onto the longhorn box and run MSBuild - almost treating the Longhorn machine as a single machine build lab.

    This build step could easily be a scheduled task to achieve some kind of continuous integration.

    And Gavin's Question: is it possible to customise build rules so that C++ files also get linted as part of the compile step.

    YES! This is a great example of the kind of thing that MSBuild enables. You could invoke a <Lint /> task (or use Exec if you only have a command-line tool available) as part of the build process. This could be placed right before the Compile target.

    Certainly you can filter the files that would be passed into a task. This could be done in a number of ways. As you say, you could use directories or filename extensions to control it. Also we support the notion of Metadata on Items in MSBuild, so a LINTable file could be defined like this:

    <ItemGroup>
    <Compile Include="MyFile.cpp">
    <LintMe>true</LintMe>
    </Compile>
    <Compile Include="MyOtherFile.cpp">
    <LintMe>false</LintMe>
    </Compile>
    </ItemGroup>

    Then you could use syntax like the following in a target:

    <CreateItem
    Include="@(Compile)"
    Condition="'%(Compile.LintMe)' == 'true'">
    <Output TaskParameter="Include" ItemName="Lint" />
    </CreateItem>

    <Lint Sources="@(Lint)" />

    ..Kieran
    PM, MSBuild Team
  • Brilliant Kieran, that's just what I wanted to hear. Thanks!
  • Neat, they finally stole ant
  • It will be interesting to see what happens to NAnt when MSBuild hits the streets.
  • It will be forced to improve and innovate to remain in use - I can't wait.
  • Ha! Just when I was in the middle of converting all of my old non-vs (N)makefiles to Ant!  
Page 1 of 1 (8 items)