Tuesday, January 17, 2006

Differences between NAnt and MSBuild

It's been a while since my last post, but I am back to make the comparison I previously promised between NAnt and MSBuild. Why? Mostly to learn about MSBuild. Partly to help with conversion between NAnt and MSBuild. I should point out right away that there is no explicit need to convert NAnt scripts to MSBuild. You can exectute NAnt from within MSBuild as a Task. Finally, I have not achieved guru status with either NAnt or MSbuild, so please rectify any mistakes below with a helpful comment.

That being said, on with the comparison:

1. NAnt has functions. MSBuild really has no such thing. MSBuild is infinately extensible via Tasks, but there aren't that many tasks as compared with NAnt functions. I think this is a sign of maturity in NAnt. Since MSBuild's programmers had NAnt to look at, we do have to wonder why they excluded some things but we can guess that dev timelines ran out.

2. NAnt has a few fileset types with specialized attributes. All file references in MSBuild are contained in ItemGroup blocks. However, with ItemMetadata providing infinite extensibility to each Item in an ItemGroup, the specialized attributes are not required.

3. In the main, the NAnt schema tends to be attribute centric, while MSbuild favors elements with text content. The NAnt schema also favors lowercase names, while MSBuild favors an initial capital.

4. NAnt allows fileset groups to be included inside a target. MSBuild Targets may only reference ItemGroups specified as children of the Project element.

5. MSBuild seems to be missing the notion of a basedir. This basedir attribute is very helpful in NAnt. MSBuild only has the project root as basedir, and can use PATH variables. Again, I think the maturity of NAnt shows in this oversite. Obviously, you can define a Property with an appropriate base directory Uri and append it to every path in an ItemGroup. You could probably also make use of ItemMetaData if you were writing a custom Task.

6. Property references in NAnt are denoted by ${}, while MSBuild uses $(). What is this, C# versus VB? You also cannot use '.' characters in your property names in MSBuild, though it is legal in NAnt.

7. MSBuild references Items in an ItemGroup with the syntax @(ItemName). NAnt references filesets by id utilizing a refid attribute without decoration.

8. There are 72 built-in tasks in NAnt. There are 35 in MSBuild, however most of the common tasks related to .net use are in there. They both include an Exec(exec) task for calling out to the system. They both allow you to write your own to extend the functionality of the build. So, if it can be done in code, you can run it from either one.

9. Both allow conditions to be placed on nearly every element to determine if the build should include the enclosing item. However, NAnt uses both an 'if' and 'unless' approach, where MSBuild just simply has 'Condition' that supports '!' (not); 'And'; and 'Or'. Here the MSBuild approach seems more streamlined.

10. MSBuild Projects can have multiple default targets, and also has an InitialTarget which can be run before other targets for prepatory steps. Utilizing 'depends'/'DependsOnTargets' attributes you could craft your own workflow in either program. Similar to the Default, you can have multiple targets specified in the DependsOnTargets attribute which is an interesting enahancement over NAnt.

11. A subtle difference in the CSC Task is that in NAnt, the warnings to ignore are elements which each have a condition. In MSBuild, warnings are a single attribute which contains a semi-colon delimeted list. In NAnt, you could conditionally ignore some warnings on some builds based on criteria. No such thing would be possible in MSBuild.
Submit this story to DotNetKicks

1 comment:

gabe19 said...

There are community tasks available at http://msbuildtasks.tigris.org/