June 17, 2004

Using Nant for Windows Kernel Mode Compiles

Well, today I finally bogged down and tackled the world of Nant for automated builds.

Back in April I talked about test driven development in .NET, and discussed how I was looking for a heterogeous solution to build both my .NET code (C# standalone apps) and my DDK code (C kernel drivers), with the final result being able to integrate it with testing tools like NUnit, FxCop and Static Driver Verifier. Nant is designed to build .NET code, but definitely not made for calling DDK compiles directly.

So I wrote a simple kludge today to make it all work nicely. The trick is to realize that the DDK compile environment is nothing more than a cmd window executing the setenv.bat script, allowing you then to run the build -cef within said target. This allows you to target different kernels for different operating systems, different CPU types (32/64bit) and check (debug) or free (release) builds.

So I simply wrote a batch script (I sure felt dirty doing that) which wraps all that functionality, and have that batch script simply return a success or failure to the cmd line. Once that was done... I just set up the Nant environment to call it through <exec>, looking for a simple status code... and walla... automated builds. On a side note, in over 12 years of batch scripting experience I never knew that exit /b 1 existed. What a find. It allows you to force an override return code. Apparently this was adding in WXP. Nice touch!

Anyways, my build file for Nant is actually pretty simple. The part that is interesting for this discussion is basically:


<target name="debug" description="Set debug property for project build">
     <property name="debug" value="true"/>
</target>
<target name="debug-drivers" description="Build Debug Security Driver for all Platforms">
     <property name="debug" value="true"/>
     <call target="drivers"/>
</target>
<target name="drivers" description="Build Security Driver for all Platforms">
     <call target="W2K-driver"/>
     <call target="XP-driver"/>
     <call target="LH-driver"/>
</target>
<target name="W2K-driver" description="Build Security Driver for W2K">
     <exec program="./Tools/drvbuild.bat">
          <arg value="W2K"/>
          <arg value="debug" if="${debug}"/>
     </exec>
</target>
<target name="XP-driver" description="Build Security Driver for XP/WS2K3">
     <exec program="./Tools/drvbuild.bat">
          <arg value="WXP"/>
          <arg value="debug" if="${debug}"/>
     </exec>
</target>
<target name="LH-driver" description="Build Security Driver for Longhorn">
     <exec program="./Tools/drvbuild.bat">
          <arg value="LH"/>
          <arg value="debug" if="${debug}"/>
     </exec>
</target>

The interesting bit is that the drvbuild.bat file takes care of the CPU targets as well as take care of prefast and driver verifier stuff. By using the neat little if="${debug}" to trigger passing in the debug arg, I can basically build a single driver on the fly or all of them:


nant drivers          # Creates release drivers for all kernels
nant debug XP-driver  # Creates Checked version of XP driver
nant debug-drivers    # Creates debug drivers for all kernels
nant LH-driver        # Creates release driver for Longhorn

Yes I know this is pretty boring stuff. But the hard part is over. Now that I can target any kernel, for any CPU, in both Release and Debug builds using the same tool through Nant, I can now port the .NET stuff in and have scheduled daily builds without incident. I just finished adding the ability to have Nant update my internal devteam RSS feed, so not only does it build all my kernel mode code, it updates the feeds to alert all subscribers to the new build's availability.

Posted by SilverStr at June 17, 2004 01:43 PM | TrackBack
Comments

Hi, this is very useful. Is it possible to see the drvbuild.bat?
Thanks

Posted by: david at November 4, 2004 04:42 PM