Is there a good reason to switch to MSBuild?

I have a new coworker (hey Sheraz!) the last couple weeks who’s hellbent on becoming a development guru overnight.  He’s keeping me on my toes with a bevy of questions.  Today’s question was “why are we using NAnt instead of MSBuild?”  My answer:  mumbling, then “because I know how to make NAnt dance and it isn’t broken.”  I’ve got years of experience with NAnt and it holds no real mystery for me, so I don’t see any real reason to trade one set of Xml markup for another.  In the circles I run around in I’d bet NAnt is still the most common tool. 


Am I missing anything cool?  Anybody used both and found a strong technical reason to prefer one or the other?


Rake is a different animal altogether.  That I can see as an advantage for more complex scripts.

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://code.google.com/p/fake/ Steffen Forkmann
  • http://tobin@tobinharris.com Tobin Harris

    I looked briefly at Rake, Nant, Boobs, Psake and MSBuild.

    All look cool in particular ways. I thought I’d try my own for a bit of fun, does this idea look good to anyone? (http://shrinkify.com/drk
    ) Or just a waste of time?

  • HB

    The Boo Build System…

    I like it just because I get to type “boobs” at work…

  • Sheraz

    Hey Jeremy,
    my oppologies for keeping you on your toes. It’s just that it’s hard to find someone with such amount of knowledge and I can’t afford to loose this opportunity. About making NANT to dance the way you want to… I totally agree but (with capital B) it’s like saying that i’m going to use MFC because I get all the power I need. I say that use the right tool at right time. If MSBuild can get the work done easily then why not use it. But your point about NANT working without breaking is definitely something that makes it worth using because MSBuild means Microsoft and hense who knows when it’s gonna break.

  • http://codeliability.blogspot.com/ Mark Lindell

    I drove our build process for the last 5 years using NAnt. We did very complex things with custom tasks and inline scripts.

    We recently converted our build system to MSBuild and the amount of build code dropped ~80%. Our build times went from 3 hrs and 20 minutes to 27 minutes.

    I feel MSBuilds metadata and input/output system is superior to NAnt and better thought out.

    Dittos on the usefulness of a ubiquitous distro.

    My $.02.

  • http://sticklebackplastic.com Matt Ellis

    I’m a bit of a nant newbie, only having maintained a single build system, but msbuild seems much more sensible (the old hindsight 20/20). Plus the integration with VS is killer.

    My project had a common targets file that was included in several top level project files that redefined properties and (occasionally) targets in the common file. AIUI, in nant the common file would override any properties/targets set in the top level files, unless explicitly marked otherwise. This is counter-intuitive and opposite to how msbuild works, where the included file is evaluated before the current file’s contents. This swung me in favour of msbuild…

    Cheers
    Matt

  • http://www.e-tobi.net Tobi

    If you can’t decide between NAnt and MSBuild, try this:

    http://code.google.com/p/boo-build-system/

    see also Ayendes comments about this build system:

    http://ayende.com/Blog/archive/2007/09/22/Introducing-Boobs-Boo-Build-System.aspx

    Looks very interesting… I will give it a try throughout the week.

  • http://www.mohundro.com/blog/ David Mohundro

    Ditto on Phil’s comment on IronRake! Though it might not be as portable or ubiquitous, I wrote my last build script in Powershell and shelled out to MSBuild for the actual compilation. It actually worked quite well.

  • http://flimflan.com/blog Joshua Flanagan

    Target overriding (build script inheritance) is definitely a very useful feature – I wasn’t aware NAnt didn’t support it.

    joeyDotNet – I put together a prototype Boo build DSL wrapper over MSBuild. You’d create your script in Boo, and when run it would generate the MSBuild project (not XML, but the object representation) and then execute it. I had big dreams for it, but a lot of the more advanced features of MSBuild became difficult to support so I quickly lost interest. I should probably post the code so that someone with more motivation could go after it.

  • http://dotnet.org.za/scott Scott Dukes

    For me the most useful “Feature” of MSBuild (over NAnt) is the ability to redefine targets. At first glance this seems a like a strange design decision, but it can be incredibly useful.

    I have create a single MSBuild .targets file that defines the entire build process for my team. It works equally well for applications with a singe project and those with hundreds.

    All that is required to use it is to create another MSBuild file (build.proj in my environment), that imports the targets file and defines the relevant itemgroups and properties as well as re-defining certain targets. IMO this is a very clean separation of concerns.

    It’s also easy to extend – I have another .targets file that handles publishing the application via ClickOnce. Again all it does is import the base .targets file and re-defines the Package and Publish targets.

    This was much harder to do with NAnt – in my old build system I had to create hook dependencies which were only executed when the hook targets were defined:
    i.e.


  • http://clipmarks.com/clipper/travislaborde/ Travis Laborde

    What a great post and set of comments!

    I’m interested in the Continuous Integration stuff even though by far most things I work on, I work on alone. So, I’ve been wondering about this very debate, trying to figure out which one I’ll try to learn first.

    I really appreciate all the comments and links!

  • http://joeydotnet.com/blog Joey Beninghove

    Ok, here’s a challenge for someone (probably Ayende). Don’t have the time to do it myself right now…

    And I even have a name for it already.
    Bake! A build engine using a Boo DSL. :)

    *I’d* use it…

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @Phil,

    Before he converted to Ruby fulltime, Jay Fields put together an equivalent of the old NAnt task in Rake over a single night. Which means a mere mortal could do that in about a week. Using Rake may not be that far out there.

  • http://ggreig.livejournal.com/ Gavin Greig

    We started off with NAnt and switched to MSBuild because of its better integration with Visual Studio. We migrated all our NAnt scripts to MSBuild over a fairly short period of time.

    However, at the time we didn’t have a big investment in NAnt, so it wasn’t that hard to migrate.

    There’s no truly compelling reason to switch, but I think over time MSBuild does just reduce the impedance on a number of things, all of which have been mentioned by previous commenters. If you have a big investment in NAnt, don’t commit to migrating your old scripts, but try it on a new project.

  • http://haacked.com/ Haacked

    We should build IronRake!

    I’m kind of the opinion that XML is not the right language for a build script. A DSL in ruby (or IronRuby) makes a lot of sense.

    However, I will probably stick with NAnt or MsBuild for the time being due to their ubiquity for building .NET projects.

  • http://www.lostechies.com/blogs/jason_meridth Jason Meridth

    @Matt, I’m curious what makes targets more clear than NAnt or MSBuild.

    Jeremy,
    Potato, Potahto. They are too similar to make a switch. And like you said you can call MSBuild from NAnt if one of your developers just HAS to go that route and you want to use his part of the deployment (of course with full intention to re-write in NAnt later).

  • http://flimflan.com/blog Joshua Flanagan

    I don’t think you will find a strong technical reason to use one over the other. I think the reason most people you know use NAnt is because it was available well before MSBuild, and MSBuild doesn’t offer a compelling reason to make them switch. I’d also argue that NAnt doesn’t offer a compelling reason to switch either.
    MSBuild saves you a few megs from the bin/tools section of your code repository (since you can safely assume it is already on any target computer). You’re “svn co” takes a little less time. Like I said, not a strong technical reason.
    I’d be curious to know what functionality people believe is missing from MSBuild. Once I include the MSBuild Community Tasks (think NAnt.Contrib), I have all the functionality I’ve ever needed for build and deployment scripts.
    If you are interested in learning MSBuild, feel free to send some questions my way. I might be able to make some interesting “MSBuild for NAnt users” blog posts out of it.

  • jeremy

    we use msbuild for compilation and rake for everything else. we use CruiseControl.rb for CI so everything fits together nicely.

    we didn’t feel obligated to go with nant or msbuild since we didn’t have prior experience with either.

  • Rajiv

    Many mention abt msbuildtasks.tigris.org have you guys checked out http://www.codeplex.com/sdctasks
    there are over 300 msbuild tasks in it. We use Nant for builds and MsBuild (with sdc tasks) for IIS related stuff that are not available from Nant or NantContrib tasks.

  • http://nldd.lordabdul.net lordabdul

    Although NAnt is apparently more powerful and easier to learn than MSBuild, along with a bigger set of tasks and functions and all, I tend to prefer MSBuild:
    - because it’s installed by default, and it’s the native VS format.
    - because the way items and metadata works. It’s a bit hard to get used to it, but after a while, you get to do very elegant stuff in a few lines.
    - because there is virtually nothing in the schema beside calling tasks. I’ve seen several projects where the build system in NAnt (or similar) gets very complicated, and you actually end up with a lot of logic in the XML file. The problem is that you can’t debug that when something goes wrong. Instead, MSBuild is poor, compared to NAnt’s powerful functions, so you have to write some of that logic in tasks, which are debuggable (because they’re in C# or VB.NET). In the end, I find that engineers responsible for the build spend less time writing easily maintainable and isolated tasks than having to fight 2000 lines of XML.

  • Tucker

    I’m one of those that calls msbuild from NAnt to do the compilation and NAnt for everything else. It’s great to just be able to point msbuild to a csproj, sln, or wdproj and have it work just like building in VS, but I had trouble wrapping my head around how to do all the things I can easily do in NAnt.

  • Matt

    Ant, Nant, Msbuild and Rake all have the same problem: they fundamentally misunderstand what a “target” is, and therefore make builds far more complicated than they should be.

  • Troy Gould

    @Sneal

    Regarding ItemGroups. If you want lazy eval of Items, then use the CreateItem task instead. I wish that were documented more clearly by Microsoft!

    Is batching is the same as foreach in nant?

  • Peter Mounce

    I struggled through a fairly full-featured MSBuild build project from scratch (no project, no prior knowledge) about 2/3 of a year ago. It does assembly-versioning, debug-or-release, unit tests, ncover + ncoverage, fxcop, and output-packaging-into-a-zip file. I desperately want to refactor it now that I found http://dotnet.org.za/cjlotz/archive/2007/04/04/part-1-continuous-integration-using-msbuild-cruisecontrol-net-fxcop-nunit-ncover-subversion.aspx about 3 months ago; that’s a great series of blog posts that I wish I’d found earlier!

    Anyway. I really dislike MSBuild’s syntax re: collections; it’s confusing to wrap my head around.

    Since then, I’ve wanted to move to nAnt, mostly for the greater tool support (there’s a free nAnt addin for VS.NET) and apparently better google-ability. I found that there doesn’t seem to be much to choose from between MSBuild and nAnt in terms of task-support; I didn’t need anything that isn’t provided by both (either out of the box, or with the aid of google).

    ReSharper supports both, which is really nice.

  • http://blog.sneal.net Sneal

    Although NAnt has more features and a slightly lower learning curve, the one thing I really like about MSBuild is its batching capability. Create a few item groups with metadata (or use the one’s in your csproj file) and you can just run those items through a custom task with minimal effort that’s included into your csproj file. Additionally with MSBuild you can hook right into the build pipeline of VS without the need to use a before or after build event by overriding the BuildDependsOn property group.

    The one thing that really annoys me about MSBuild is that ItemGroups aren’t lazily evaluated, which makes copying build output potentially annoying.

  • http://brewder.blogspot.com Brian Brewder

    It sounds like you guys probably have the resources for a full time build guy. I’ve worked on the build process for the product I work on and have found that a visual tool (we use FinalBuilder) is much easier to learn and maintain unless you work on the build regularly (I have tried NAnt and MSBuild).

    If you are interested, I wrote a blog post about the tool we use, Making the Build – http://brewder.blogspot.com/2007/06/making-build.html.

  • Troy Tuttle

    Ditto on the previous comments. There is a MSBuild Community Tasks project that boosts you to a decent position without having to get custom http://msbuildtasks.tigris.org/. Also, keep in mind if your shop is doing mostly .NET 2.0 stuff, the MSBuild runtime is ubiquitous. Our shop uses MSBuild to do deployments (mainly simple copy tasks, configuration management, and logging). And since everyone has .NET 2.0 installed on their workstations as a part of the corporate image, anyone with security permissions can do a deployment for us.

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @Kevin,

    It’s easy just to shell out from NAnt to use MSBuild just to do the compilation, and I’d suspect that’s what most people do, so the VS integration isn’t really that big of a deal.

  • josh

    shrug.
    no affinity to either here. msbuild is easier to get going with because vs solution and project files (>=2005) are msbuild files.

    I feel nant is more mature and extensible, but msbuild is off to a good start. I just like that know nant means know a build engine on windows and *nix.

    msbuild is easy if you only care about basic build & output options. nant gives you more power at the cost of complexity.

  • http://kevindwhite.blogspot.com/ Kevin D. White

    The argument in favor of msbuild is that it is used by Visual Studio to build projects. Therefore it is easier to achieve a state where a build initiated by Visual Studio performs exactly the same steps as the automated build. For some groups this is a major positive.

    The argument against is two-fold. First, the base tool is capable of nothing more than building and logging. A lot of time will be spent finding or writing custom tasks. Groups that lack a dedicated build developer will spent a substantial amount of time writing tasks. Second, msbuild is designed with a bad assumption that most inputs and outputs must be strongly typed. This creates substantial friction for new developers.

  • http://www.opgenorth.net Tom Opgenorth

    Having used both, I think my answer would be that it boils down to your personal preference. Personally, if I’m starting from scratch I would use Nant, but I wouldn’t throw away a good MSBuild file. Or, if the client I was working for was a die-hard MS shop with a real hate one for open source, I’d just shrug and use MSBuild without worrying about it.

    The one reason I usually stick with Nant is because it’s more mature, and has more tasks for doing stuff. That being said, on one project where I was using MSBuild, I found it pretty easy to port the Nant task I need to MSBuild.