Expert Delivery Using NAnt and CruiseControl.NET
Disclaimer: I got this book free as a giveaway for our .NET Developers Group. Some folks might think this could influence my opinion, but they'd be wrong. Also, Marc Holmes is in no way related to me. (Well, we're both humans inhabiting the Earth, descended from Adam and Eve or the same biological soup depending on your beliefs, so I suppose that's not completely true.)
Note: To avoid possible confusion due to our same last names, through the review I'm going to refer to the author as "Marc ," not "Holmes."
I got this book because I'm an independent software geek who loves having automated, repeatable processes. I don't have a QA department to double-check every drop I send to customers, nor do I have a separate process department to run checklists every time I need to gather up some statistics on testing, code complexity, etc. I need all these sorts of tasks wrapped up into stable, repeatable, automated processes so that I don't have to constantly worry whether I've forgotten something. (Worse yet, I work from home while taking care of two young children. Automated processes let me focus my meager remaining concentration on software construction while having stuffed animals tossed on my keyboard and drums bashed behind my work chair.) I've had a solid background in Ant and NAnt, but wanted real-world detail on how to generate an end-to-end process for continuous integration and delivery.
This book is part of Apress' "Expert" series which includes books on Oracle, .NET development, web services, and Network Time Protocol. (And who among us hasn't frequently needed an expert book on NTP when we're trying to remember some details of symmetric passive mode?)
Two mantras run centrally through this book: Marc's quip "Design for Delivery," and the importance of standards-based processes. It's not enough to cobble together an automated system which may get one from end-to-end. A team needs a system which gets software built, tested, reported, and packaged in a form read to drop into a customer's environment. Having the mindset of "Design for Delivery" helps focus the team on meeting the goal of getting their software out the door in best fashion. Approaching an automated build system with a thought to standardization means that the team shoots for systems applicable to many projects. Each new project's solution shouldn't require a large amount of rework to get the build/deploy system up and running. Marc is emphatic about this throughout the book, constantly refactoring build and deploy scripts to keep them as abstract as possible.
Marc approaches the task of creating an automated delivery process with the same mindset of designing software: a few use cases with expected outcomes which are used as guidelines for building up the various scripts needed to get delivery tasks done, standards for wider implementations are considered, then the scripts themselves are built in an iterative fashion.
This book isn't a fluff-filled overview of tools. Marc dives down deep into the guts of several very useful tools, showing readers how to solve tough, real-world problems. Simplistic build and deployment systems which do nothing more than run a compiler and zip the resulting output are, well, simple to build.
Theory and details of how a tool (or tools) might be used are fine, but then reality in implementation hits. Marc matter-of-factly states that his approach to a delivery system may not work for everyone. Many of the tools he demonstrates offer multiple approaches to solving problems, such as NAnt's ability to use different build files via inclusion or as separate targets. Marc almost always discusses these options and discusses the rationale for his selection.
Marc also includes some great "Further Reading" sections at the end of most chapters. He points readers to some terrific additional reading such as McConnell's Code Complete, 2nd ed., Ambler's Agile Database Techniques: Effective Strategies for the Agile Software Developer, and Newkirk's Test Driven Development in Microsoft .NET.
The book's flow is very sensible and straightforward. Marc opens with a good discussion on creating a delivery system, then moves on in chapter two to a example of one company's project which he carries through the entire book. The example project is expanded during subsequent chapters as Marc builds up the build and deployment scripts as he covers that chapter's topic. I found this particularly useful since it's a great guide to building one's own automated system. It's easier to follow one example through an evolutionary process rather than having different examples thrown out piecemeal.
The book's laid out in ten chapters plus two appendices. After the first chapter's introduction, each chapter covers one key concept in the build system. Chapter ten closes out the book with "Closing Thoughts."
Chapter 1, "A Context for Delivery," lays out Marc's ideas on why automated, standardized build systems are so critical. Marc doesn't waste time detailing examples of train wrecks due to bad delivery processes. He has a short blurb on the business benefits of automation, then gives an overview of his example company, Etomic, and its products.
Marc continues by discussing potential processes for delivery, covering potential problem issues with each option, laying out his case for standardization and automation in the delivery cycle. Readers who are looking for rescue from a chaotic build and delivery process should hopefully have an epiphany moment or two in this section. So may readers who already have some process in place.
Chapter 2, "Dissecting NAnt," gives an introduction to NAnt and discusses its basic features. The ubiquitous "Hello, World" example is used, then the chapter moves on to discuss the details of creating build files, and variations for invoking NAnt from the command line. There's some good detail on using loggers to generate and merge output from NAnt into an XML log file, important for tracking exact execution details. NAnt's all-important properties, configuration file options for controlling NAnt's execution, are also covered in good detail.
Marc finishes the chapter by creating a skeleton build file for the fictitious Etomic corporation. This skeleton is expanded upon in following chapters as Marc discusses other tools and processes.
Chapter 3, "Important NAnt Tasks," is where Marc gets into the weeds of NAnt's execution. NAnt tasks are chunks of functionality contained in NAnt's libraries. Tasks give NAnt users support for things like interfacing to CVS for source code control, calling NDoc to create documentation from XML comment files, and reading values from the Windows registry. Marc selects several groups of tasks to cover, including conditional tasks for controlling build flow (if, ifnot, fail, e.g.), file management (attrib, copy, mkdir, get), and the fundamental build tasks (asminfo, exec, mkiisdir, solution, csc).
Marc also introduces NAnt-contrib, a second library of tasks written by other NAnt community developers. These tasks, which haven't yet made it into NAnt's framework, provide critical, additional functionality such as interfacing to Visual Source Safe for configuration management.
While he details important tasks in clear fashion, Marc makes it clear that his book is not a reference for the tools he covers. He emphatically points users to the tools' sites for more current and detailed information.
Marc carries this theme throughout the book: he focuses on what's necessary to get the job done, briefly describes potential enhancements or other possibilities, then points the reader to sources for more information.
Chapter 4, "A Simple Case Study," finally gets to the "real world" implementation. Marc begins to fill in the skeleton developed in Chapter 3 with tasks for testing via NUnit, documentation via NDoc, and error handling via NAnt's 'nant.onfailure' property which points the build process to an error-handling task.
Versioning software during a build can be difficult, but Marc has a section in this chapter devoted to handling versioning. He also shows opportunities for refactoring the build file from its klunky initial form to something less brittle and more easily extended. He also leaves the build file behind to begin development of a separate deployment script. He admits his initial deployment script is overly simple and suitable only for basic Windows applications; however, he continues to enhance and expand the deployment script as the book progresses.
Chapter 5, "Process Standards ," seems misnamed to me. Marc does spend some time discussing naming conventions and source control organization at the start of the chapter; however, most of this short chapter centers on refactoring the single build file into separate chunks.
Additionally, he covers a more complex build and deployment example with a custom-written Visual Source Safe Manager component which utilizes COM interoperability and is installed as a Windows service. Both these features are some of the more complex issues one might tackle in real-world deployments, so Marc's text here is very useful.
A semi-hidden gem in this chapter is Marc's discussion of a tip for getting around the less-than-helpful structure of a Web application in Visual Studio .NET 2003. Microsoft forces developers to hack up virtual links to an IIS server's web publishing folder, then scatters Web Application files between the .NET solution's directory and the web folder. This causes great difficulty when trying to use NAnt to build and deploy web apps. Marc points readers to Fritz Onion's wiki site where a clearly explained procedure for changing VS.NET's web application behavior awaits.
Chapter 6, "Continuous Integration ," pulls CruiseControl.NET (CC.NET) into the picture. Marc starts the chapter with great discussion on the benefits of Continuous Integration (CI), then begins detailing the tools. Marc chooses CC.NET, but he also gives a short bit of coverage to two options, Draco.NET and Hippo.NET. His "Further Reading" section for this chapter also points out other options.
Marc's coverage of CC.NET is much as his coverage of NAnt: targeted, detailed discussion of the features needed only to implement his build and deployment system. He writes about the Web Dashboard and the useful cctray applications, then moves to basic configuration and setting up the server. There's brief but adequate coverage given to configuring triggers, source control integration, and publishers, plus Marc points out what changes are needed for the NAnt build scripts. Marc closes the chapter with summary screens and output from CC.NET runs, then mentions how CC.NET is easily extendable if one needs additional functionality - providing a good transition to the next chapter.
Chapter 7, "Extending NAnt" is a great tutorial on how to write your own tasks to cover jobs not in NAnt or NAnt-contrib's libraries. Marc uses 'mkdir', 'copy', 'version', and 'exec' to help readers learn the basics of writing their own tasks in NAnt. He discusses NAnt attributes, crucial to NAnt's framework, then moves to how individual tasks interact with the master build file for capturing events, reading properties, etc.
Marc's first example of extending NAnt to incorporate FxCop is educational, but has been overcome by events: FxCop support is included in NAnt-contrib version 0.85rc3. Regardless, it's very useful to see how simple it is to write one's own task in NAnt.
Chapter 8, "Database Integration" is by far the longest and intricate chapter. Right off the bat Marc lists some of the hardest problems to solve when integrating databases into a build system: lack of source control, the amount of detail one must pay attention to, and how to deal with data in the database itself.
Marc puts forth examples of shared and local database development, then moves on to build/deploy tasks involved in integrating databases. He also covers how these tasks thread into the continuous integration process. Next he covers modifying the build and deploy scripts to integrate the database tasks.
The brunt of chapter 8 revolves around wrapping Red Gate's SQL Bundle, a commercial tool package, into the processes. Marc shows how Red Gate's tools enable the process to automatically detect database schema changes, create merge or update files, and compare database instances. This chapter alone might make the book worth its price if readers are involved with any projects needing substantial database development.
Chapter 9, "Code Generation," makes use of CodeSmith, a code generation package in both freeware and commercial formats. Marc espouses code generation as a way to alleviate problems in complex build environments.
Specifically, Marc identifies three troublesome topics: separation of concern (intertwining of process and configuration information), specific system steps (unavoidable hard-wiring in of file names for NDoc's documentation, for example), and administration overhead (the work required to keep the build/deploy systems operational or portable to new projects).
Marc's use of CodeSmith demonstrates how code generation can solve these problems and wrap directly into the build process. He uses short, clear examples on how to tie CodeSmith into both NAnt and CruiseControl.NET.
Chapter 10, "Closing Thoughts," is Marc's summary. It's a walkthrough of the territory the book just covered, laying out the material in brief form. Context, motivation, mechanics, consequences (pros/cons), and results all get concise summaries. The author also lays out a very useful Best Practices list for processes, standards, NAnt, CruiseControl.NET, and other factors. He also spends a very few paragraphs on the direction Microsoft is taking with their upcoming Build Server and its potential impact on the NAnt community.
The mechanics and format of this book are terrific for the most part. The author's writing style is clear, easy-going, and humorous without being campy. The index appears to be very complete and covered the few things I needed to reference.
On the negative side, a few of the screenshots weren't framed or cropped very well, leaving me looking for a magnifying glass to try to figure out bits the author referenced in his text. However, this was the case with only a few graphics. Most were very clear and viewable.
Additionally, the versions of tools covered in this book are somewhat outdated, but the author makes that very clear in several places through the book. All his examples work for the versions referenced in the book. Additionally, a complete download of all the various build files, tools, and source code examples is available from Apress's website.
This is a terrific book for folks in the .NET arena looking to establish an automated build and delivery system. It's a very good book for folks looking to enhance an existing automated system, particularly if you're looking to solve the really difficult problem of wrapping database integration into your system.
Lastly, I'd say it's a very good book for anyone interested in automated build and delivery processes, regardless of the environment you're working in. Java developers can get great material from this book, just as I got great ideas from Loughran's Java Development with Ant.
You can purchase Expert .NET Delivery Using NAnt and CruseControl.NET from bn.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.
Is that a Tom Cruse Control?
been there done that been there done that been there done that
My brain hurts.
bluespaceradio.com - New Wave, Indie and Alternative
Isn't that what spyware/adware uses??
Take the cheese to sickbay, the doctor should see it as soon as possible - B'Elanna Torres, "Learning Curve"
Someone please write a review of this very long review so I can discern if it's a worthwhile read.
If the review of the review shows that the review is worthwhile, and it is ultimately favorable to the book, I may then read the book.
I'm a big tall mofo.
Wow does that conjure up horrible images of my car showing the BSOD right before I realize I can't get out of cruise control...
*shudder*
Don't anthropomorphize computers: they hate that.
Are there are open source tools to do static analysis of C#? It seems like it should be pretty straightforward to check unused code, idempotent operations, etc... you'd need a lexer, a parser, an AST generator, a symbol table, and maybe some data flow analysis. Then you could crank out whatever rules you wanted.
Seems both useful and doable, but Googling a bit only turned up commercial tools...
The Army reading list
Man that was stuffed with so many hollow calories I am so bloated with buzzwords.
Sounds like a good book. Build systems are often overlooked by the development community, in favor of "sexier" topics like technologies and standards. It's important to scale the build process with the complexity of the team and project, however -- I'm sure the author covers that. A mention of TOAD would have been nice, as well, especially when talking about DB source control.
Integration into larger enterprise architectures would also be a critical subject, as most of us develop in some kind of larger environment that has it's own tools, standards, and processes. In other words, I get the feeling from the review that the book is more "blank sheet" build control than "big corporate" build control. There's a difference.
Giant Bathroom Sponge Found Orbiting Saturn! Film at Eleven
You realize this isn't MS right? These are just OSS developers porting tools to another platform. Isn't that a good thing?????
"reality has a well-known liberal bias" - Steven Colbert
Parent isn't a troll... Okay... it is. But it is very true. I got an "F" on a paper in third grade for doing the same thing. Book review != Summary.
See my journal for slashdot ID's by year. Mine created in 2005. http://slashdot.org/journal/289875/slashdot-ids-by-year
first one to count how many times the words "Automated" and "Delivery" are used in the above review gets a cookie. ...
BEGIN!
Here is a brief review of the review:
.NET developer. My advice is if you plan on reading his review, go straight for the book.
Although, elegantly spoken, the review lacks content. The review seems to be nothing more but chapter summaries taken straight from the book. The only unique information the author seems to present is that the book is a great read if you are a
I guess they should just start from scratch right? And I mean from scratch right down to the hardware level. Every language/tool build on the backs of others. In fact I would say that _humanity_ does this. It's called "knowledge"
"If I have seen further it is by standing on ye shoulders of Giants." --Isaac Newton
MS has nothing to do with CruiseControl.net or NAnt. These are fully Open Sourced projects built on the backs of other Open Source projects.
I thought it was about information sharing and freedom. Not bias and bullshit. But I could be wrong.
Yes, but did you make hundreds of dollars in affiliate commissions from Barnes and Noble for writing your summary disguised as a book review?
If not, then you really didn't come close to doing the same thing as this person.
Automated builds aren't for users, they are for developers. Continuous integration combined with autmoated builds insure that:
1. Once you compile a module and check it in, it will be tested by automated unit tests before it is released to other members of the dev team.
2. All the members of the dev team stay in sync with each other.
3. QA Testers have the latest "good" version of the code as soon as it is released.
4. Software changes that break unit tests are not released to QA nor to the end user.
I tried; I couldn't do it. About 20% in, I started losing focus, my pupils became dilated, and I simply could not continue. I tried willing my brain to go on, but there must've been some kind of safety override.
Is understanding what you are actually posting about an idea whos time has come and gone with you?
Do not try to read the dupe, thats impossible. Instead, only try to realize the truth
What truth?
There is no dupe
Other tools that I've used to get a complete continuous integration cycle up and running for a large development project I'm currently working on are Subversion (for the server) and TortoiseSVN (for developer PCs). They are full-featured, free, and work well with NAnt/CC.NET out of the box.
A book on how to use an alphabet soup of tools to make your .Net project run smoothly
scores higher in the review than books by Richard
W. Stevens (9/10)? Get real. Stevens' works are
classics, this is just a cookbook for hapless idiots
slaving in the .Net saltmines, spending their valuable years on something that'll be replaced by the New Shiny Fixes Everything WidgetFoo from Microsoft in a few years.
Automated: 12
Delivery: 19
Did he really say "ye"?
West Coast slashdotterz have probably been to this
leather bar.
Thanks and have a Karl_Rove_Free_Day,
Kilgore Trout, CEO
Jesus man, cease and desist!
I'm curious why you think the software that is released would be different from what the what the testers tested.
Seriously dude, are you a developer? Say it aint so.
It sounds like you are looking for NDepend.
--
Automated build can be for users though. When a version is released it can be built by an automated system with consistency, this is how all major development houses ship their products. Otherwise you may throw the monkey wrench of human error into the mix. Good build systems can deliver full end products, including fully burned CD-Roms/DVDs, programmed IC's, etc.
Of course it's up the development team to determine if this process is worth the cost.
Or "Think of the poor customer." This is good for developers to remember, especially in enterprise-class systems. Most developer's view of the world begins and ends at the source-code control system. Often building and deploying software in production is an afterthought. And db schema and user customization/localization is often overlooked, even when decent build and deployment processes exist. Probably this schism exists because companies reach a size where they split development, QA, support, and consulting into separate departments who often never interact in meaningful ways. End at the end of the day, the customer's perception of how good your code is has nothing to do with the quality of its design and build, but how understandable, supportable and deployable it is.
The name of the book is Expert.NET Delivery Using NAnt and CruiseControl.NET and it is not Expert.NET Delivery Using NAnt and CruseControl.NET as given in the review.
Most teachers are unwilling to give poor grades on qualitative assignments like papers.
Say it louder! Automated builds just allow programmers to write more code faster and we all know that will lead to even more bugs and problems.
The real solution is to make programming as painful as possible. I truly believe that keyboards should be spiked - small needles in the center of each key - so that programmers will type slowly, or not at all. Everyone knows that the program with no code also has no bugs!
Further, programmers should *pay* for each line of code they write. Instead of automated builds, we want a new arm of government that will knock on programmers's doors at 3am and ask them "are you really sure". A kind of "code police", perhaps.
I'm all for the death penalty not just for writing viruses, but also for writing code that is not smart enough to build itself without automation.
Lastly, today's tools make life too easy. I think compilers were a bad start, and it only got worse from then. Don't talk to me about interpreters, or that half-breed zombie, the opn-the-fly compiler. As for portability... when I was a lad, portability was a 40lb luggable with a 1" screen. The only true way to program is to have to enter the bytes one by one using toggles, backing-up to punched tapes made of metal. You need to feel the pain!!! Especially as the tape shoots out of the reader and slices your arm off.
You can also grab this in PDF ("eBook") from Apress directly at half-price. Look to the "purchase as eBook" link on the right.
No kidding! Can you imagine what would happen if you automated builds to make sure the pieces fit together? You think things are bad now, wait till you automatically know if there is a problem!!! The book even talks about automated testing. Are they bloody crazy!!!! Can you imagine the problems caused by automatically finding errors/issues in code without spending hundreds of man-hours manually going through every test for every build????? I hope this never comes to pass!!!!
Can I now be modded "Interesting" for saying absolutly retarded shit to? (No disrespect meant to the mentally handicapped by grouping them with parent)
"reality has a well-known liberal bias" - Steven Colbert
FxCop.
- pd
I was thinking of "delivery" as a network thing, as in "media content delivery" or "software and update patch" delivery. What an incredibly vague article summary.... "delivery"...
Sounds familiar. .NET part of the Mono project?
Isn't
"If I have seen further it is by standing on ye shoulders of Giants." --Isaac Newton
This often misused quote was actually a perjorative Newton used against a competing physicist of short stature.
Right off the bat I can see several crucial elements missing from this book: the distribution manifest. How do you assemble distributions and their components? Distributions are rarely, if ever, one complete product. A typical large product will contain a *lot* of sub-components and if you're working with cross-platform components, like I do, then how do you handle them? How do you tell the build system what to build *without* a manifest?
Then there's the knotty problem of scheduling. If you're building a release distribution a week, you need a hard-core scheduler to keep up with the demand.
It seems to that this is a pretty low-level book. Any build-manager with a reasonably complex build system should be looking at something like Parabuild. Or a scheduler like Maui.
Patriotism is a virtue of the vicious
That's automated build, genius, not automated release. It's part of the build process, not the release process...
It's official. Most of you are morons.
NJava, so I can run ant, hibernate etc on .net w/o any whoring.
I wouldn't describe my university job as a salt mine type operation. Heck, I'm on the 3rd floor only the Ops guys are in the basement.
The thing is, I agree that Stevens' book is a classic. It laid out POSIX compliant systems for me in a coherent way that no man pages ever could. But your point is lost in demagoguery about Microsoft's evil.
But I see you've been modded down to 0 as a troll.
>I'm curious why you think the software that is released would be different from what the what the testers tested.
As an example:
@time x: You write code that uses zlib version 1.00. You test it and it works.
@time x+1: Zlib releases 1.01. It's broken, or fixes a bug that was broken in version 1.0. This
causes your code to break.
@time x+2: users download your code + zlib 1.01 (the latest release).
User gets broken code. Developer gets complaints.
What user compiled isn't what was tested.
>Seriously dude, are you a developer? Say it aint so.
Why are you so rude to people you've never met?
I didn't piss in your cornflakes, and said nothing rude about you, so take your attitude elsewhere please.
-- Programming with boost is like building a house with lego. It's a cool but I wouldn't want to live in it
Is this a some kind of new Scientology offshoot?
Gentoo portage is an automated build system and also
an automated delivery system. Is civility a concept you understand? Perhaps you might consider it as more than just an outdated concept.
-- Programming with boost is like building a house with lego. It's a cool but I wouldn't want to live in it
have this deep humour-impairment deficiency?
Cruise Control is a waste of time. It's big, it's bloated, and it's horrible at handling large vs.net solutions (try to use Cruise Control on a solution that has re-used code, and thus has projects distributed throughout your source control system: you'll find that you have to maintain your ccnet.config in parallel with your .sln).
Tell me one thing you can do with CruiseControl that you can't using Nant/NantContrib and a job/scheduled task. With Nant you can get-latest (also by label and autobuild), it has a nice solution task for building Vs.net solutions
you can handle email notification in nant (rendering CC's notification a bit redundant IMO).
Sure, Cruise Control has some fancy bells and whistles like Agents squaking on your screen that the build failed, but and the end of the day, CruiseControl is just an unnecessary layer of complexity on top of Nant, which can handle the job just fine.
Best, most USEFUL article I've seen on /. in months.
So refreshing to read something by a true software person who isn't some emotionally twisted geek obsessed with hating all things Microsoft.
Good work. I'm off to order the book now.
"Ye" is actually just "the". Early typescripts used the letter 'y' to replace the old English letter 'thorn' which made a 'th' sound.
So yes, he very well might have said 'ye', but he would have pronounced it 'the'.
But why did people need to create .NET-specific versions of these tools? Ant and CruiseControl are pretty much agnostic of development platform. Sure, if you want to extend Ant you need to do it in Java... but c'mon, it's a build tool. Your build tools don't have to be made using the same language as the project you're building with them!
What? Are you simple or something? The build process isn't going to produce a deployable package if the build fails.
I'd reccommend you read the book because it looks like you really need to learn how to deliver working code.
Funny thing, When .NET developers port Open Source projects to their platform, the Java guys get all huffy about 'stealing'. It's open source guys! The whole point is that we can take your source and port it to a our platform. Thanks the tools are great, but if you embrace OSS, you embrace OSS. What's next an OSS licence that only allows usage by slashdot's 'ideologically sound' sources.
.NET users by the thought police of slashdot coming on. Remember Slashdot is watching you.
Ah I feel a purge of the ideologically unsound
He needs to be controlled!
bookpool sells this book for $24.95 instead of $44.95.
This(8) chapter alone might make the book worth its price if readers are involved with any projects needing substantial database development.
Ah, but that chapter can be had for free from Apress website. That chapter indeed is a good read. I had looked for good solution to this problem a month ago and found none close to my satisfaction.
I apologize, it was uncalled for and was meant more as a joke.
The idea of a different library breaking the code is a very real thing, like you showed. But that does not mean automated builds are a bad thing. An automated build system can guarantee that the package that you develop is the same package that gets tested and eventually released to the user. But outside dependencies cannot be controlled by this type of build system.
Thanks! :)
I haven't been able to come up with any answer to
the 'outside dependencies break my code'. Well,
other than the obvious one, remove all outside
dependencies. Which isn't always very useful since
a program with no outside dependencies is not
very useful (other than games). Since I see
many other systems experiencing it too, I guess
they haven't either (or just haven't addressed
it).
Have a good one.
-- Programming with boost is like building a house with lego. It's a cool but I wouldn't want to live in it
Ok, so I've used both ant and make, and my personal view is that ant is a retarded pain in the ass, and make is an elegant, general tool.
That being said, can anybody tell me what's wrong with make that we need half a dozen other tools to control builds? The fact the Windows doesn't come with a real shell out of the box doesn't count. If you're gonna download a build tool, you might as well pick up cygwin/mingw/sfu while you're at it.
I think make's syntax is much cleaner that ant's XML, and since every make command is just a shell command, there's no need to learn another special purpose language just for your build system. Make also starts up faster since it doesn't need to initialize a JVM or JIT anything (though this could be alleviated by compiling ant with GCJ). Ant seemed to have some type of dependencies, but it didn't seem to support the file based dependencies that make does.
I haven't use Ant for a while, and I haven't used NAnt at all. If I have any misconceptions here, I'd appreciate them getting cleared up.
Sex Toys I found this great web site thought I owuld share with everyone else. I am a woman looking to maybe get into the sex toy biz and I found this site useful to help get me started.