Integrating Build and Developer Studio



Soon after I started working on commercial products targeted for the Windows
NT operating system, I realized that there was no way that I was going to
put up with the hideous command line oriented build shells that come with
the NT DDK. I like nice, gui-oriented, integrated development environments
reminiscent of the Unix days with an X terminal with XEmacs running on it to
glue together everything from my email to source code control.

Environment

There are a couple of small features that I insist on in order to do serious
software development:



I demand syntax coloring. I want my RGB. There is no way I am going to stare
at monochrome pages of source code. I would go blind. I’m not kidding.



I insist on automated browsing. I personally can’t remember more than about
3 or 4 things at any point in time, so navigating quickly from an object to
its definition with a click of the mouse is just about my speed. I surround
myself with computers to extend my mental capabilities, not strain them.



When I get a compilation error, it is non-negotiable that I must be able to
click on the error message and have my nose rubbed in my own stupid code
errors. I will never again count lines or demand that my editor insert
hideous line numbers into the source display. The same goes for getting
syntax for an API interface. I must be able to cut and paste from the
description of the interface into the source code I am editing, without any
major shuffling of display real estate.



My team must use software repositories and automated build facilities. I
don’t know about you, but for me source code control works like this: when I
attempt to alter a file, if the file is under source code control it gets
checked out. This method, it turns out, is one of the best practices in
software engineering for testing the validity of source code modifications.
In other words, you and I should always have our checked-in source code
under some sort of regularly scheduled build discipline.



I refuse to use more than one basic programming environment per operating
system. You won’t catch me using one set of tools to create drivers and then
a totally different set of tools to create the applications that use those
drivers. I have enough trouble keeping one set of tools house trained.



Oh yes, one final thing: if the operating system vendor says that device
drivers must be built using the vendor supplied build utilities, then well
of course all of the features above must work in conjunction with the vendor
supplied build utilities.



Limitations

Now it turns out that Microsoft Developer Studio (Visual C++ 4.x aka MSDS)
together with Source Safe (or another source code control tool that is
compatible with Developer Studio), does everything I want…er, almost
everything. For some reason (which I cannot fathom and care not to comment
on), there is no support in Developer Studio for building device drivers (Oh
yes and the editor is a little lacking in the extensibility department, but
so much else is right with Developer Studio that I am willing to ignore
this).



Yes, I’ve seen the stuff put forth by MSDN about how you can hack driver
support into Developer Studio. How charming. I really want to hack device
drivers. I don’t know about your customers, but our customers actually get
upset when our products don’t work. I’d much rather use processes that are
not in the category of Use At Your Own Risk. Oh yes, and there are a few
other small things, like support. Just suppose you happen to trip over a
defect in NT while testing your device driver and wish to have Microsoft
actually support you in resolving this claim. I think that if I were
Microsoft, I wouldn’t even start to listen to your problem until your device
driver was built using the supported build utilities.



Solution

So, here is what I did, and in retrospect, it wasn’t a big deal. Rather than
some hard to get right and fragile custom build procedure, all I use is one
shell script, ddkbuild.bat, and the external Makefile project type in
Developer Studio for my driver development.



The shell script is rather simple (given that it uses the dreadful DOS
shell, it must be simple): It takes a couple of command line arguments, runs
the setenv.bat file from the DDK, and produces a build for you (free or
checked, as you command). The script then does some postprocessing of the
output from build, and creates browse files for you (if you are nice).
Finally ddkbuild confronts you with all of your stupid coding errors. (FYI,
all of this occurs inside the MSDS IDE). When ddkbuild completes, you just
click on an error message and you are beamed right up to your error. There
are two major limitations: You have to have your source tree in the DDK
distribution tree, and your drivers are placed in %BASEDIR%\lib\ (you have
no choice in this decision). Feel free to modify ddkbuild to overcome these
limitations, or to extend it in any way you see fit.



Using ddkbuild.bat

In order to understand the ddkbuild process let’s walk through the creation
of a simple dd. project.

Startup MSDS and select File/NEW/Project Workspace.



From the New Project Workspace dialogue select Makefile as the project type.
Choose a name for your project (I’m using demo) and a location within the
dd. tree. For my example, the location is C:\DDK\src\osr\demo. Click
Create... and select Yes when MSDS asks if you want to specify command line
settings. You should be at the Project Settings dialogue (shown the next
picture.).





[Image]





     For the debug build, your task is to make your window look as follows:







[Image]









(The Build command line should read ddkbuild checked %BASEDIR%\src\osr\demo,
the Rebuild all line should read -cf, the Output file name is not needed but
I used demo.sys in the example, and finally the Browse info file name is
demo.bsc), and like figure z for the free build.

The only change between the Debug and Release versions is that the Build
command line for the Release version replaces checked with free.



[Image]



OK. So far pretty easy, right? Now there are one or two other steps you need
to take. First, make sure that you have the DDK bin directory in your MSDS
path. (Look at the Tools\Options\Directories dialogue – mine looks like
figure xx).





[Image]





You may also want to set the include directories here as well (shown in
figure yy).





[Image]





Now start adding files into your project. For my example lets just have two
files: demo.c and SOURCES. The contents of the SOURCES file for this project
look like this:



                    MAJORCOMP=ntos

                    MINORCOMP=demo

                    NT_UP=0



                    TARGETNAME=demo

                    TARGETPATH=$(BASEDIR)\lib

                    TARGETTYPE=DRIVER



                    INCLUDES=$(BASEDIR)\inc



                    MSC_WARNING_LEVEL=/W3 /WX /FR /FAcs



                    SOURCES=\

                    demo.c



We need some driver source code, of course. I just plunked the simple driver
from the dd. samples (%BASEDIR%\src\simple\sys\ldunld.c) into demo.c, which
ought to do for now.



We aren’t quite ready to build yet, though. You need to copy the Makefile
template into the build directory. Now you should be able to just click on
the build menu in MSDS and build should be invoked for you. If all works
well, you ought to get some output in your build window in MSDS like that
shown in figure zz.

          -------------------Configuration: demo - Win32
          Debug--------------------



          build in directory C:\DDK\src\osr\demo with arguments (basedir
          C:\DDK)

          run build -e -M for checked version in C:\DDK\src\osr\demo

          BUILD: Using 2 child processes

          BUILD: Compile and Link for i386

          BUILD: Loading C:\DDK\build.dat...

          BUILD: Computing Include file dependencies:

          Scanning c:\msdev\mfc\include

          Scanning c:\msdev\include

          Scanning c:\DDK\inc

          Scanning c:\DDK\src\osr\demo

          Scanning demo.c

          BUILD: Examining c:\DDK\src\osr\demo directory for files to
          compile.

          c:\DDK\src\osr\demo

          c:\DDK\src\osr\demo - 1 source files (194 lines)

          BUILD: Saving C:\DDK\build.dat...

          BUILD: Compiling c:\DDK\src\osr\demo directory

          1>Compiling - demo.c for i386

          BUILD: Linking c:\DDK\src\osr\demo directory

          1>Linking Executable - c:\DDK\lib\i386\checked\demo.sys for i386

          BUILD: Done



          1 files compiled - 194 LPS

          1 executables built

          =============== build warnings ======================

          build complete

          building browse information files

          ddkbuild complete

          demo.sys - 0 error(s), 0 warning(s)



Now go ahead and play around with it. Put some errors in the source file and
rebuild.

What, you want to browse too? First you need to add a line to your SOURCES
file:

          MSC_WARNING_LEVEL=/FR

This adds the /FR switch to the compiler invocation, so when you compile
your driver, a .sbr file gets created. You also have to invoke BSCMAKE, so
you need one more file, a file called sbrlst.txt in the top directory of
your project. The existence of sbrlst.txt triggers ddkbuild to invoke
bscmake. In its simplest form sbrlst.txt just contains:



          /o demo.bsc *.sbr



Now when you build your driver, you get a browser tags file too, and when
you click on a variable you can jump to its definition. Cool eh?