nAnt: The master build file
Posted on February 13th, 2009
If you have been following along with the other nAnt articles, this is the final step of setting up your base project. From here you will be able to add additional projects, processes, etc. Then if you have a CI server (cruise control.net, Team City, or some other solution) you are ready to go.
Ok so without further ado here is the master build file for our sample project.
<?xml version="1.0" encoding='iso-8859-1' ?> <project default="build" xmlns="http://nant.sf.net/release/0.85/nant.xsd" > <property name="root.dir" value="${directory::get-current-directory()}" /> <include buildfile="${root.dir}\common.xml" /> <fileset id="buildfiles.all"> <include name="${root.dir}/NantSupportLibrary/default.build"/> <include name="${root.dir}/NantBuildSample/default.build"/> </fileset> <target name="build" depends="cleanup common.init display-current-build-info"> <echo message="${directory::get-current-directory()}"/> <echo message="${root.dir}"/> <echo message="${root.dir}/common.xml"/> <nant> <buildfiles refid="buildfiles.all" /> </nant> </target> </project>
As you can see there is not really a whole lot different in this file than a standard build file. However we will start at the top.
The very first thing we do is set our “root.dir” property. Now I did this one a little differently to show you another way to do things if you wanted to. You can also just replace this line with the following in the sample project code and it will work just fine:
Either one will work in this case. Since this file is in the root of our source tree it’s just set to the current working directory.
Next as with the other files we include our common.xml file.
The next thing is a little new. Since this considered to be a master build file what we are going to do is setup a fileset that will tell the build file where all the project level build files are.
Important: The order in which you include the files is important. They will be executed from top to bottom so make sure you have any dependencies figured out and built in the proper order.
Last but not least we have our build target. This is the sucker that starts all the work. As you can see we have several dependencies. The first is a “cleanup” step. This will cleanup our output folder so we can make sure we always have a nice clean build. Next it runs the “common.init” again to make sure our output folders are in place and that we have our project.sources defined (needed to compile the code). Lastly we call the “display-current-build-info” target. This will display some of the settings we have, framework version, etc. you can add to this output in the common.xml file if you feel the need.
Once all those are run we get into the core of the task. Here we are going to essentially have nant spawn instances of itself to run all the build files we defined up above. It will basically loop through that list and run each build file sequentially.
Well that’s about it. Your ready to run the thing. If you downloaded the zip file you can just run nant in the root source folder and it should spit everything out for you.
After it’s done running you should have your output in the output folder.
I hope you enjoyed these posts and it helps you if you plan on using nAnt as a build tool. In the future I will add more articles that build off of these. Things like adding unit testing, calling external objects, using extensions like nAntContrib, etc.
If there is anything you’d like to see drop a line and let me know.
Download the zip sample project.
nAnt: The project build file
Posted on February 13th, 2009
Next in the series surrounding nAnt is the process of creating the individual build files for each project. This is assuming of course that you are wanting a DLL, EXE, or what have you for each project in your visual studio solution. If you just want everything to compile into 1 dll or exe you can do that too with some minor adjustments of course.
This project file will assume that you have the common.xml file that we built in the last nAnt article. If you do not have it that is ok, it is included with the sample code for this article.
First things first lets create our build file by adding a new xml document object to our project.
Below is a basic project file we will use.
<?xml version="1.0" encoding='iso-8859-1' ?> <project name="NantSupportLibrary" default="build" xmlns="http://nant.sf.net/release/0.85/nant.xsd" > <property name="root.dir" value="../." /> <include buildfile="${root.dir}/common.xml" /> <target name="init" depends="common.init"> <assemblyfileset id="project.references" basedir="${build.output.dir}"> <include name="System.dll" /> <include name="System.Core.dll" /> </assemblyfileset> <resourcefileset id="project.resources"> </resourcefileset> </target> <target name="build" description="Build ${project::get-name()}" depends="init common.compile.dll.cs" > </target> </project>
You will notice that the first thing we have is the Project tag. This is the most root level element you can have. Just like the common.xml file you need to set the name and default command to run for the project. Also, make sure you have the xmlns element set correctly for the version of nAnt you are running.
The very first thing we need to do is set our root element. Basically we have the root.dir element to help ground everything to a consistent path structure. Makes having a common file and build process much easier. The root.dir property should use the syntax needed to get back to the root of your source tree. So if root level for the project is down one level you use “..” if it’s two levels “../..” etc.
Next we need to include our common.xml build file. The syntax as you can see if very straight forward. Now if you have not seen it before anything enclosed in a “${}” is special command for nAnt to do something. It is effectively a token, variable, parameter, etc. In the case of this include line it is concatenating the value of the variable root.dir with “/common.xml”.
Once we have that our project file will have access to all the targets we setup in the common file. So let’s setup a “init” target to initialize the filesets and other various things we need for this particular project. Since this project is pretty basic, as you can see, we do not have a whole lot in here. First we depend upon the “common.init” target from our common build file that defines our fileset for build files. Next we setup our assembly and resource file sets. In the Assembly fileset you will add a line for each reference you need in your project. If you have project references to other projects in your solution then add the appropriate project output reference here. In the sample I have this so you can see what I mean. If this was a windows forms app you would have resx files included in your resourcefileset element.
Last but not least we create our build target. This is what will be called when we run this build file. As you can see it depends on our “init” target we just created and “common.compile.dll.cs” from our common.xml build file. The description element actually will output the project name from the top of the build file.
One thing to remember the name attribute of the project element must be the name of the compiled object that you want to output. So if you wanted it to be “MyApp.Is.Awesome.dll” your project name would be “MyApp.Is.Awesome”.
In the next article we will walk through creating the master build file which will actually run all this stuff and provide what you want. A working build of a project.
Download the sample code
nAnt: Getting your machine ready
Posted on January 27th, 2009
In this post we will get your pc ready to use nant. The examples and links will be geared towards VS2008 however they will also work for VS2005. VS2003 requires a bit more but can be done in very similar ways.
- If you have not already done so go get nAnt. This example and all future ones will use version 0.85
- Extract the file to a location on your c: drive like c:\tools\nant
- Add the location of the bin folder to your path. So in this example it would be: c:\tools\nant\bin or c:\tools\nant\0.85\bin depending on how you extracted your files.
- Copy the file nant.xsd from the c:\tools\nant\schemas folder to the following location(s):
- C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas — for visual studio 2005
- C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas — for visual studio 2008
Now that you have done all that we are going to open visual studio. This next bit will work in either 2005 or 2008 so the instructions will be the same. Once you have opened visual studio.
- Go to the Menu: Tools -> Options
- Navigate in the left hand tree to the Text Editor section
- Select the File Extentions item. Your options dialog should look like this:
In the Extension box I want you to enter the word: build- Note: I use build as the extension for my build files for nant vs xml so I know what they are out of the box.
- For this option dialog you do not put any periods in the extension box.
- Next select XML Editor from the list and then hit the Add button. Your options dialog should then look like this:
Now select OK and off we go.
That’s it for the setup. If you want to test this add a new XML File to a project in Visual Studio and call it something like default.build. You should then get intellisense for your build files. The root level object will be project. As you will notice because we added the file extension you also get the auto-complete benefits of the xml editor. Things like adding the closing tag, quotes, etc.
That takes care of the first part of our nAnt setup. In the next article I’ll walk you through adding Item and Project templates that you can use and customize for easily adding build files and projects that already have build files to your project. After which we will get into the usage of nAnt and setting up a common build file that you can reuse from project to project.
Building your code or CI and you
Posted on January 27th, 2009
I’ve been seeing alot of stuff on the web lately considering continuous integration (CI), automated builds, build tools, unit testing, etc. Figured maybe it’s time I start to post about some of this stuff. I’ve been using CI in various shapes and sizes as it were for many years. From custom rolled solutions to full commercial packages. As such I will be posting many articles around CI, builds, unit testing, etc to help people who maybe have never seen it before or even if I’m lucky have an answer to a problem you have been having.
First let me say that I don’t care if you are a single person shop, team, department, or whole company. You NEED to be using some form of CI. There are free versions out there like Cruise Control.net and TeamCity (which is now free for limited installations). I personnally have setup a TeamCity installation on my big developer desktop and I’m just a one person show for the stuff I do at home.
So, what is CI and why should you use it. CI is a means by which you can have an autonomous process running somewhere either on your machine, server, cloud computing platform, server farm, you name it that will take your code and compile it. Big whoop-dee-do you say I can do that by just building from my desktop in my IDE. Ok, that’s great if you are a one person shop. But what happens if you don’t get the latest from your source control and yeah it builds with the code you have but your buddy in the cube across from you just changed everything. Now your build won’t work but you don’t find out till later when somebody says something. This is where CI comes into play. It does not remove the build check from your box. You should always do that. Where CI comes in is a sanity check and a means to automate tedious tasks. Using the scenario above what happens when two people check in code at the same time such that you both think everything is working but then in the morning you get latest and bam nothing compiles. Wouldn’t it have been nice to have something email you telling you that it broke and maybe even why. What about unit tests. Do you use them, run them, all the time, some of the time, etc. You could have all this automated for you upfront.
Now setting up a CI system is an upfront task, yes it takes some time, yes there could be integration issues with your code base, yes you may need to change the way you build code. But in the end it’s all worth it. Once you get onto a CI system and everything is up and running you will start to get a sense of peace. Not only that but you will quickly come to rely upon it. It becomes that great little tool that you wish you had found sooner.
Now the catch. If you don’t use a Source Control provider at the minimum CI wont’ do much for you. You really should be using source control. This comes back into the you MUST do this category. Again I don’t care if you are just one person or a whole company. You NEED source control.
Why is this important if you are a single person. Well what happens when you inadvertantly delete a folder with code and you had no backup. Come on how many tech people do you know who actively backup there stuff? If it’s not automated we don’t usually do it. Let’s even say that you are working on some project that you might want to sell. How do you know if you have everything. Just because your folder is there doesn’t count. What happens if you need to have somebody help you code the app, so you just went from being a one person show to a small team. If you have source control your golden. Just give them access and away you go. It is an important process and does not need to be strictly used for source code. I’ve used it for word docs so I can go back and pull say a version 1 of a requirement spec to show the business unit / partner how things have changed over the course of say a year or even a month. You just never know.
CI needs source control. It provides a means by which you can have a 3rd party verify your code base. In a single person shop it can tell you if you have really checked in all your code. So let’s say you the one man team are working on two or more computers. If you have source control it’s easy to share all your code across the wire and know that you have everything because your CI build is working based on what is in the repository.
Another good use of CI is that in most tools you can even setup scheduled builds, say like a nightly build. What if you have a project where you want to provide a nightly build to people. You could setup your build script to actually take all your code build it and zip it. The CI server can do this for you. So no late nights, waiting for people to finish. You can then even have the CI server send you emails when it succeeds or fails.
The advantages to running CI and source control are to many to number. If you haven’t ever used them I suggest you do so. Go get Subversion and TeamCity at the minimum and install them. Work through them, play with them, and use them. They will save you time, money, and effort in the end.
In the next posts I hope to show you how to get a subversion installation up and running on Windows along with configuring TeamCity to use the same setup. I’ll even start posting some topics on using nAnt and unit testing.
The more we can test and automate our build and deployments the more time we can spend actually coding our solutions.