For a current project I decided to use MSBuild (for various reasons). The build script is used to automate a build and delivery process that was previously handled manually. I have worked a lot with build scripts during the last few years but I have only used NAnt, so it was fun to learn and try something new.

Although MSBuild is a different build framework it shares some fundamental concepts with NAnt (xml based, targets and dependencies, etc.). After some googling I did not find any real-world MSBuild example, but I happened to know that Rhino Commons is one of the VERY few open source projects that use MSBuild and it was a great reference for a good structured build file.  

The Good: One of the nice things that you can do in MSBuild is declare data by using ItemGroups, the data can contain meta data and that meta data can be consumed and used by tasks. Here is an example:

<ProgramFiles Include="$(OutDir)_PublishedWebsites\WebApp\**\*">
  <PackageDir>www\site.com\WebApp</PackageDir>
  <DevelopmentDir>\\integration.int\d$\Inetpub\WebApp</DevelopmentDir>            
</ProgramFiles>
...
<Target Name="PushToIntegration" DependsOnTargets="CreatePackage">        
    <Exec Command="xcopy /E /Y /D &quot;$(ReleaseDir)\%(ProgramFiles.PackageDir)&quot; &quot;%(ProgramFiles.DevelopmentDir)&quot;" />
</Target>

The Bad: Properties and ItemGroups are evaluated when the build scripts starts executing. In order to create properties that is based on some dynamic data (like time) you have to use tasks and output parameters like this:

<Time Format="yyyy-MM-dd HH:mm">
    <Output TaskParameter="FormattedTime" PropertyName="BuildTime" />
</Time>

This is very annoying. The syntax is even more cumbersome when you have to create dynamic ItemGroup data by using the CreateItem task. I am really missing the NAnt helper functions that can be used inside property values and conditionals. Example:

<property name="machine" value="${environment::get-machine-name()}" />
...
<if test="${target::exists(machine)}"> 
  <call target="${machine}"/>
</if>

I guess if I would choose between MSBuild and NAnt for a personal project I would probably choose NAnt, but it is not a clear winner, they both have their strengths and weaknesses.

Here are some other comparisons: