Книга: Writing Windows WDM Device Drivers
build Utility
Разделы на этой странице:
build Utility
The DDK build command line utility is the primary tool for building drivers. It invokes the nmake make utility to build your driver using the correct compiler and linker settings. If necessary, build can be used to build standard user mode Win32 executables, etc.
The next section describes how to invoke build from within Visual Studio. However, you must still set up build so that it can be run at the command line. As well as your source code, you must specify a SOURCES file, a standard makefile, the directory structure, and optionally a makefile.inc file and a dirs file. All these steps are described in the following text.
build displays progress details and error results to its standard output. In addition, it lists the errors in a file called build.err, the warnings in build.wrn, and a log in build.log. In W2000 there are free and checked build versions of each of these files, i.e., buildfre.log, buildchk.log, etc.
makefiles
Younger readers may not have come across makefiles. In the days before Integrated Development Environments (IDEs) such as Visual Studio, you had to use makefiles to determine which files in a project needed recompiling. If you changed only one module in a project consisting of eight modules, you want to recompile only that one module and then link the whole lot together.
The nmake utility uses instructions in a file called makefile to determine what commands to run to update a project. The following makefile shows that if haggis.cpp has been updated, it is compiled into haggis.obj using the cl compiler. haggis.obj is linked to make haggis.exe using the link tool.
haggis.exe: haggis.obj
link –o haggis.exe haggis.obj
haggis.obj: haggis.cpp
cl haggis
Most makefiles are a good deal more complicated than this, which is why they were happily forgotten when IDEs came along. However, setting up the compiler and linker settings for drivers is quite a complicated task. Therefore, Microsoft has stuck with makefiles. See the Visual Studio nmake documentation for more details of makefiles.
SOURCES
build looks for an nmake macro file called SOURCES in the current directory for details of what to build.
Listing 4.1 shows the SOURCES file for the Wdm1 project. It specifies that the driver target name is Wdm1.sys, that it is a WDM driver, and that it should be built in the OBJ subdirectory. Source browser information should be generated. The DDK inc directory is added to the search list for header files. The SOURCES macro specifies a list of files to compile. NTTARGETFILES specifies some post build steps, as described in the following text.
Other less common SOURCES macro definitions can be found in the DDK documentation. Note that there must be no spaces between the SOURCES macro and its equal sign.
Listing 4.1 Wdm1 project SOURCES file
TARGETNAME=Wdm1
TARGETTYPE=DRIVER
DRIVERTYPE=WDM
TARGETPATH=OBJ
BROWSER_INFO=1
INCLUDES=$(BASEDIR)inc;
SOURCES=init.cpp
dispatch.cpp
pnp.cpp
DebugPrint.c
version.rc
NTTARGETFILES=PostBuildSteps
makefile File
You must provide a standard file called makefile as shown in Listing 4.2. This invokes the standard make file makefile.def in the DDK inc directory.
As it says, do not edit this file at all. If you want to add to the list of files to compile, add them to the SOURCES macro in the SOURCES file.
Listing 4.2 Wdm1 project makefile
#
# DO NOT EDIT THIS FILE!!! Edit .sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE ${NTMAKEENV)makefile.def
build Directories
Windows 98 and NT
build always puts the compiled object files in the OBJi386 subdirectory (for x86 targets). The SOURCES TARGETPATH macro specifies where the final executables go. If you specify OBJ for this, then the driver executables go in the OBJi386free and OBJi386checked subdirectories. There is a long-standing bug in build that means that you have to create these last two directories by hand for build. if you were making Wdm1 from scratch, then you would have to make subdirectories OBJi386free and OBJi386checked.
Both the free and checked builds put their object files in the same directory. If you switch between these build types, make sure that you rebuild all the files in the project (by putting "-nmake /a" on the build command line).
The checked build output file OBJi386checkedWdm1.sys contains the debug symbols.
The build process also generates a file called Wdm1.dbg with the debug symbols in the OBJi386free directory.
Windows 2000
In W2000, build keeps the free and checked build object files separate. If the TARGETPATH is OBJ, the free build x86 object files and the final driver go in the OBJFREi386 directory. The checked build object files and driver go in the OBJCHKi386 directory.
Wdm1 Directories
The end result is the following series of subdirectories for Wdm1.
Directory | Contents |
---|---|
OBJ |
Has build list of files to build in _objects.mac |
OBJi386 |
W98 Compiled object files |
OBJi386free |
W98 Free build Wdm1.sys |
OBJi386checked |
W98 Checked build Wdm1.sys |
OBJFREi386 |
W2000 Free build objects and Wdm1.sys |
OBJCHKi386 |
W2000 Checked build objects and Wdm1.sys |
Other build Steps
Another makefile called makefile.inc is invoked if you use certain optional macros in the SOURCES file. Table 4.2 shows the macro name and when the make target is invoked.
Table 4.2 SOURCES optional macros
SOURCES macro name | When invoked |
---|---|
NTTARGETFILE0 |
after dependency scan |
NTTARGETFILE1 |
before linking |
NTTARGETFILES |
during link |
Listing 4.3 shows the standard makefile.inc that is used in all the book software projects.
Listing 4.3 Book software projects makefile.inc
PostBuildSteps: $(TARGET)
!if "$(DDKBUlLDENV)"="free"
rebase –B 0x10000 –X . $(TARGET)
!endif
copy $(TARGET) $(WINDIR)system32drivers
The line in the Wdm1 SOURCES file that says NTTARGETFILES=PostBuildSteps ensures that the target PostBuildSteps is built during the link process. As the PostBuildSteps target depends on $(TARGET) — the driver executable — the build commands for PostBuildSteps are carried out after the driver is built. The PostBuildSteps output is displayed in the build.log file. Note that problems in PostBuildSteps may not evident unless you inspect this file.
The actual post-build steps in makefile.inc do two jobs. First, the rebase utility is run on the driver executable for free builds, and the driver is copied to the Windows system32drivers directory. Copying the driver does not mean that it is installed.
rebase strips any remaining debug symbols that are left, even in the free driver executable. The base load address is kept at 0x10000 and the symbols are put in the .dbg file in the current directory.
DIRS File
The final main feature of build is that it can recursively build files in other directories. If a DIRS file is present, build looks at the DIRS directive in there for a list of directories to build. These directories may themselves contain further DIRS files.
The book software base directory has a DIRS file with the following line:
DIRS=Wdm1 Wdm2 WdmIo UsbKbd HidKbd DebugPrint PassThru
Running build in the book software base directory will compile the drivers in all these directories. The companion Win32 user mode applications are not built by this process.
The directories listed in the DIRS directive must be only one level below the current directory. Therefore, the Wdm1 directory has a DIRS file that instructs build to go to the SYS subdirectory.
- Building Programs with make
- Using the autoconf Utility to Configure Code
- 8.1.4. Module Build Infrastructure
- What is needed to build a NAT machine
- fwbuilder
- Chapter 2 Building and Deploying a Run-Time Image
- Build Options
- Building the Source Yourself
- Building the sendmail.cf File
- Building on Mono's Libraries
- Verifying File Integrity in ext3 File Systems with the fsck Utility
- 4.3. Kernel Build System