Before delving into the differences, I'd like to point out that NAnt is wonderful. We love the fact that there is a lot of community involvement around NAnt and NAntContrib in enabling everyone to "build" .NET applications. We certainly expect both NAnt and MSBuild communities to interop nicely, and so you should expect to see MSBuild tasks that can build NAnt projects, and vice versa. If I am not mistaken, NAnt tasks for building MSBuild projects exist today.
It's easy to enumerate of the technical differences between NAnt and MSBuild. However, I'd like to point out a fundamental philosophical aspect of MSBuild - i.e. MSBuild delivers a platform for build. In that regard, we aim to solve some of the key issues at the platform level rather than pushing that responsibility down to the project author or task author. This leads to technical differences in how dependencies are analyzed, for instance. Some of the technical aspects are noted below:
Build Input/Output Analysis: We believe that dependency analysis of build inputs and build outputs should be something that the build engine understands inherently. Project and task authors should not have to worry about analyzing dependencies. To this end, dependency analysis is done at the target level and not at the task level. You can specify build inputs and outputs at the target level.
Project Items: MSBuild supports the notion of "items" that participate as inputs into the build. Tasks consume and emit Items. Items are rich, and support metadata. The concept of project items also enables MSBuild to be "Toolable".
Toolability: MSBuild was designed to be integrated with other hosts. The best example of a host is Visual Studio 2005. However, the MSBuild engine can be hosted by any application willing to do so. Apart from being able to host the engine, you can also write tasks that are "host-aware", and can richly interact with the host to enable richer functionality.
Build Engine for Visual Studio: Visual Studio 2005 hosts MSBuild and uses MSBuild project files as the basis for all managed projects created within VS2005. This essentially means that you can build your Visual studio 2005 projects from the command line even if you don't have Visual Studio 2005(for example, on a build machine). Conversely, you can open up "hand-authored" MSBuild projects from within Visual Studio 2005, hit F5 and run your app within the debugger.
Once again - the main (or only) difference lies in the fact that MSBuild attempts to define a platform that project authors and task authors can take advantage of. Other differences are simply technical details that stem out of this important aspect. In the future, we expect to extend the platform level features to provide even richer functionality to project and task authors. Of course, this will be done in an incremental and compatible fashion so that existing tasks and projects continue to function as they should.
Faisal Mohamood
MSBuild Team
Scott
Not at the moment, but it's a pain we feel internally as well when we work on converting our internal build process over to MSBuild. We talk a lot internally about how we can make this more extensible in later releases!
Neil
I've used NAnt for a long time. In fact at a previous employer we got so good at using NAnt that the setup for each project was only a few minutes. After working with MSBuild for about ten days I don't think I'll ever get the same level of reuse and speed.
My main complaints with MSBuild so far are:
A major point in MSBuild's favor is the documentation is in general of much higher quality than NAnt.
Thanks for the comments, it's always great to hear from someone who has spent time using other tools. For what it's worth, we pretty much share exactly your thoughts. As part of our on-going internal build conversion process we definitely hit many of the same issues. In particular, #2 can be quite a pain. We have ideas for how to fix this in future releases, though!
Neil
Hi monsoondawn,
This is excellent feedback and we really appreciate you taking the time to provide it to us. User feedback of all types (criticisms, feature requests, etc) is the driving force behind future development.
I wanted to take a moment just to address some of your particular issues in hopes of reducing some of the frustration you've had with MSBuild.
In NAnt I provide a folder and just tell it to delete everything. Simple & Fast.
[jeff] the RemoveDir task should support this - if you simply provide a folder for it to remove (as a string or item), it will remove that folder and everything beneath it. (I saw your related post to this issue, and I'll post specific help over there too :)
In MSBuild I have to first create an Item collection and then provide the collection to the Delete Task. That's twice the work for the same result.
[jeff] you don't have to create an item unless you're using wildcards. you're free to pass literals to tasks that don't expect metadata on items. for example, you could just do this in a target:
<RemoveDir Directories="$(SomeDir)\somefolder" />
or alternatively:
<RemoveDir Directories="c:\base\child\somefolder" />
and the RemoveDir task will remove "somefolder" and everything beneath it.
Emailing is another great example. A build tool that can't easily generate an email from log output is a pretty useless build tool.
[jeff] we wanted to ship an email task but we just didn't have time for version 1 :) additionally, there should be an easy way to access the log the default console logger generates. as it happens, the ConsoleLogger implemented in Microsoft.Build.Engine.dll is public and extensible; by the end of this week i'll post to the msbuild team blog an example EmailLogger that emails a copy of the log the ConsoleLogger generates :)
"You can just write a custom build task"
I'm REALLY tired of hearing this as an answer to nearly every request on this forum. Build scripts should be very easy to setup and maintain. Requiring developers to write a lot of managed code just to build their managed code is really frustrating. Yes it's powerful but it's not FAST. Every minute I spend debugging code for a build script is money lost. I recognize that some orgainzations can and will take the time to create and manage a large amount of custom build code but that is not normal.
[jeff] i totally hear you on this one. for version one, we prioritized work on the file format and the core platform knowing our customers would have to live with that throughout the duration of msbuild's lifetime. obviously this meant we had less time to develop a large set of generic custom tasks. however, there are a couple of good resources on the net that may help you for now:
http://www.gotdotnet.com/codegallery/codegallery.aspx?id=b4d6499f-0020-4771-a305-c156498db75e (from Microsoft Services UK)
http://msbuildtasks.tigris.org/
additionally, there are some scenarios where a custom task just shouldn't be required but it currently is. sometimes this points to a flaw in our file format, and we hope to fix those. creating items and properties dynamically (within a target), string manipulation, passing inputs to and gathering outputs from tasks are some of the places where we've experience pain from our file format, and we want to make it better.
please keep us informed of any specific scenarios you have trouble with so we can make sure to incorporate that into future plans.
Wacky Flow Control Names
What's wrong with the keywords If, Else, ElseIf? Why did the MSBuild team decide to spend time coming up with Choose, When, Otherwise? You wasted time and reinvented the wheel.
[jeff] we didn't completely make those names up, even if they're unfamiliar :) we modelled them on constructs from XSLT because we thought they best represented what we were trying to accomplish. you can read abou the XSLT versions here: http://www.w3.org/TR/xslt#section-Conditional-Processing-with-xsl:choose we thought perhaps some of our users would be familiar with those given the popularity of xslt these days, and i think for those who aren't familiar with them that once you discover them they make pretty good sense.
$ or % or @
Depending on the context or the Task there are three different ways to refer to Item or Property values. There needs to be just one way.
[jeff] i agree this can be confusing, and we're trying to think about some of the ways to make it easier in the future - we've even been considering your suggestion of "just one way".
Hopefully this explains some of our thinking and, even better, helps you become more productive with MSBuild.
Thanks once again for providing such detailed feedback.
jeff.
The community already has a good tool, NAnt. Microsoft has the resources. Why not employ those resources to make NAnt better? Why re-invent the wheel? It sure smells to NIH... The main difference from a my perspective (a developer's perspective) is that when I come across an issue with MSBuild (at the .dll level), I can't go in and fix it.
Anyway, a tool is a tool is a tool. Hopefully both of the tools mentioned keep on improving.
As a user who has spent a considerable amount of time working with NAnt and recently introduced to MSBuild it seems to me that Microsoft would have gained a significant amount of brand recognition and support from the development community for working with the existing tool to contrib functionality. Is the MSBuild tool a critical piece of functionality that is a major revenue driving source? I suppose if it were, then Microsoft would want to protect that asset, but if not, then it makes perfect sense to contribute to the community and work to release a common build environment based on the existing architecture. Software engineering should not be about reinventing the wheel!
$0.02 from a real user...
I'm having a love-hate relationship with MSBuild under TFS Team Builds.
I've been trying to do what I believe is a simple task; performing a custom action (code generation) just before compilation of each solution. The problem I am seeing is that MSBuild wants to use the SolutionToBuild list as raw data and do the custom task on all of the solutions and then compile all of the solutions. So there really is no concept of "For Each Solution Do these Tasks" in the TFS Team Build without overriding the Microsoft provided targets (which I would think is a generally bad idea). I also don't want to have to update each and every project file to add this customization and I don't want to modify the Microsoft standard targets.
In NAnt, I can do this in a simple loop.
Get all source code
For each solution
Run custom task (code gen)
Compile solution
Next
Run Tests
Label source code
In TFS Team Builds, Microsoft is recommending that I override a target called "CoreCompile". Now I don't know about you, but when I'm told to override a core component of a system that is shipped as a unit, I get a little nervous. I liken this to them telling me that if I want to hook into version control I should open up my hex editor and modify the Team Foundation Version Control dlls.
This use case is not uncommon, but I wasted 3 weeks trying to get it to work in Team Build only to abandon that process and go back to NAnt.
Yes I like TFS and MSBuild, but there is still a LOT of room for improvement. Unfortunately that doesn't help me today, tomorrow or next week (unless you guys are planning to release a SP soon).
What's the big difference I see between MSBuild and NAnt?
NAnt is a more mature product with a large community of task builders behind it, MSBuild is in it's infancy and we are all groping around in the dark as to how to get our jobs done.
Just my $0.02...thanks for the $0.01 change...
-Steve
There are a lot people complaining about problems when targeting Solution files in MSBuild. I think the only way to solve the problem permanently is for MS to completely ditch the Solution file format . The tasks performed by the Solution file could easily be moved into the Project schema. In fact, MSBuild actually converts the Solution file into a Project format. If the darn thing only started out in the Project schema you'd be able to accomplish your task.
From your brief description I'd have to say that overriding "CoreCompile" seems like the long way around. However I hesitate to propose any alternative without knowing what you've already tried.
There are a lot people complaining about problems when targeting Solution files in MSBuild. I think the only way to solve the problem permanently is for MS to completely ditch the Solution file format .
I fully agree on you with this. We stopped using Solution files for production builds, just use them for convenience of local development.
We also want to ditch the solution file format. It is a legacy format that we ideally would have converted to MSBuild format in Visual Studio -- this is obviously totally technically possible -- but we didn't have time in V1 to do this and do everything else. The quickest thing for us was to parse the solution file format when we run on the command line, and turn it into an in-memory MSBuild project that we can then build. (To see this project, set environment variable MSBuildEmitSolution=1. You can even keep it and modify it, but obviously it won't keep in sync if you change your .sln.)
I hope in the next major version of VS the ugly .sln format is gone and replaced with a beautiful MSBuild file. The same applies to .vcproj.
In fact, ideally we should have n-level traversal projects, not a 2-level .sln file concept. That would obviously be a more major change in VS. MSBuild is a platform - we have to persuade the Visual Studio team to do this work - but I think they are on board. It is a matter of when.
Dan
"This posting provided AS-IS, with no warranties"