Share via


Specifying Libraries

Unlike some other environments that use the LIB environment variable, the Build utility always requires the full path. The purpose of this is to eliminate any ambiguities in the build process.

For example, some build processes rely on the linker to "figure out" the correct libraries by using paths stored in the LIB environment variable in combination with a list of default libraries stored in the objects. However, this approach has the inherent (and undesirable) side effect of making it difficult to either know, or control, which libraries are used in your build process.

On the other hand, the Build utility requires you to specify the full path to each library you use. It will disable any default library lookup that the linker might try to use.

Additionally, when specifying the libraries, you should try to abstract any absolute dependencies that might exist in the path. The build process provides an asterisk (*) to take the place of the target CPU platform. You can use the BASEDIR macro to take the place of the root of the project source tree. You can use DDK_LIB_PATH to refer to libraries that ship as part of the Windows Driver Kit (WDK).

Additionally, you should use an asterisk to indicate the target platform in the path. For example, assume that you are building a typical Win32 Windows .exe file. Generally, this would require you to link against kernel32.lib, user32.lib, gdi32.lib, and maybe your own component library, mylib.lib. The following is what the TARGETLIBS macro would look like:

TARGETLIBS = \
# Note: SDK_LIB_PATH already ends in \"\*\" so you should not include it when using
# the macro.
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\user32.lib \
$(SDK_LIB_PATH)\gdi32.lib \
..\mylib\obj\*\mylib.lib

When building on an x86 platform, this would mean the same as:

TARGETLIBS = \
$(BASEDIR)\lib\i386\kernel32.lib \
$(BASEDIR)\lib\i386\user32.lib \
$(BASEDIR)\lib\i386\gdi32.lib \
..\mylib\obj\i386\mylib.lib

To build a particular set of build products, change to a directory that contains either a Dirs file or a Sources file. Run the Build utility. The utility will automatically build the products specified in the Sources file of each subdirectory.

For example, if a Sources file describes a library called "mylib", the following command line is used to build the library:

build -386

Note   When you build an NT-based, non-WDM, driver that has not been optimized and that uses the Ntoskrnl library functions, you must set the TARGETLIBS macro so that the Ntoskrnl library is first. When you set the TARGETLIBS macro in this way, the Build utility links to Ntoskrnl before it links to any other library.

Specifying the Standard C++ new Function for User-Mode Drivers and Applications

There are two versions of the C++ new function in the C run-time (CRT) import library. One version of the new function, the non-throwing version, returns a NULL if a memory allocation fails. This is the default behavior and is maintained for backward compatibility. The other version of new supports the behavior that is specified in the C++ standard. This new function, the throwing version, throws an exception if the memory allocation fails. If you are using the Standard Template Library (STL) and have included the macro USE_STL in your Sources file, by default, you get the C++ standard throwing new function.

In some circumstances, depending upon the order that the libraries are processed, the linker could use the non-throwing version of the new function. To make sure that you get the throwing version of the new function, link your binary with thrownew.obj.

In your Sources file, use the TARGETLIBS macro and the CRT_LIB_PATH environment variable to specify thrownew.obj.

TARGETLIBS =   $(CRT_LIB_PATH)\thrownew.obj

The default path that is specified by the CRT_LIB_PATH variable is %DDKROOT%\lib\crt.

For more information about these differences between the new functions, see The new and delete Operators.

 

 

Send comments about this topic to Microsoft

Build date: 5/3/2011