Build Utility (build.exe/build)

Contents:

Overview

The build utility is the core of the Shared Source CLI (SSCLI) 2.0 build process.  It is also included with the Microsoft® Windows® Device Driver Development Kit (DDK). You can find additional documentation by searching for "build utility" on msdn.microsoft.com.

The application file for the build utility is named build.exe on Windows.

This tool is a driver that uses the Microsoft Program Maintenance Utility (nmake.exe) build tool. It is responsible for:

  1. Recursing down directories listed in dirs files.
  2. Producing one binary output per directory.  Sources files contain instructions on how to produce a single binary output. This will be one of the following:
  3. Starting nmake and the other build tools, then parsing their output, to produce the build*.log, build*.wrn, and build*.err log output files.

The build utility, together with its core makefiles (in env/bin), provides a separation of build environment (compiler flags for example) from the actual description of the sources to be compiled, allowing for multiple target platforms with minimal changes to the build system. It also provides standardized error reporting, and a number of developer conveniences, such as spreading compilation across multiple processors.

The build utility searches the dirs file for the macros DIRS and OPTIONAL_DIRS. It then recurses to each directory listed where it might find another dirs file (indicating more directories to recurse into) or a sources file (indicating something needs to be built). If it finds a sources file, it looks for the macros SOURCES, INCLUDES, TARGETNAME, and TARGETPATH. These are parsed to determine the dependencies, the list of files to build, and the end result. Typically, this information is then kept in a file called build.dat that the build utility will create for future reference. Depending on the options you pass to the build utility, it performs the appropriate action and then calls a make program (For more information, see BUILD_MAKE_PROGRAM) to build the component. There are files (makefil0 and makefile.inc) that the build utility will recognize in special circumstances (for instance, only on a clean build). When the entire directory tree is built, the utility terminates.

Usage:

build [options] [~]directories

Features of the Build Utility

The build utility:

Arguments

Argument Description
directories Non-switch parameters specify additional source directories.  Specifying * builds all optional source directories.

Specifying the "~" ("not") option removes a directory from the default build.

Options

Options can be specified using either a dash ('-') or a slash ('/').

Option Description
-? Display usage message

When you use this tool on UNIX system-based platforms, /? might expand to a filename. Instead either use the /help option variation, use -?, or enclose the /? option in quotes: "/?".

-# Forces _objects.mac to be regenerated.
-$ Displays the complete dependency tree hierarchically.
-0 Runs pass 0 generation only, with no compilation and no linking.
-2 Performs only a two-pass build; does not run pass 0. (Same as old -Z.)
-3 Performs three passes, with no dependency checking or scanning of source files. Same as -Z.
-a Allows synchronized blocks and drains during link pass.
-b Displays full error message text (does not truncate messages).
-B baseline Checks the build failures against a baseline.  If there is no baseline, terminate the build on the first error.
-c Deletes all object files.
-C Deletes all .lib files only.
-D Checks dependencies before building.
-e Generates build.log, build.wrn, and build.err files.
-E Always keeps the .log, .wrn, and .err files (use with -z).
-f Forces a rescan of all source and include files.
-F Prints the full path when displaying errors or warnings to stdout.
-G Enables target-specific dirs files if and only if one target exists.
-H [n] Run only phase n of the build; otherwise all phases.
-i Ignores extraneous dependency warning messages.
-I Prevents display of thread index if this is a multiprocessor build.
-k Prevents deletion of out-of-date targets.
-l Links only, does not compile.
-L Compiles only, does not perform a link phase.
-m Runs build in the idle priority class.
-M n Performs a multiprocessor build (for MP machines) where n is the number of processors. 

If -M is not specified, n defaults to one processor.  If -M is specified but n is not, then n defaults to the number of processors on the computer.

-n No SYNCHRONIZE_BLOCK and SYNCHRONIZE_DRAIN directives
-o Displays out-of-date files.
-O Generates an obj[d]\_objects.mac file for current directory.
-P Reports the elapsed time to build each directory.
-q Queries only; does not run nmake.exe tool.
-r dirpath Restarts a clean build at the specified directory path dirpath.
-s Displays a status line at the top of the display.
-S Displays a status line with include file line counts.
-t Displays the first level of the dependency tree.
-T Displays the complete dependency tree.
-$ Displays the complete dependency tree hierarchically.
-u Displays unused BUILD_OPTIONS.
-v Enables include file version checking.
-w Shows warnings on the screen.
-y Shows the files scanned.
-z Performs one pass with compilation and linking, but no dependency checking or scanning of source files.

 

-Z Performs three passes, with no dependency checking or scanning of source files.

Same as -3.

-why Lists reasons for building targets.
-386 Builds targets for the i386.
-x86 Builds targets for the i386 (same option as -386).
-ia64 Builds targets for Itanium.
-amd64 Builds targets for AMD64
-dynamic machine Builds targets for given machine.
-x filename Excludes include file, filename, from dependency checks.
-j filename Uses filename as the name for log files.  The -j switch changes the first field, so it produces filename.log, filename.wrn, and filename.err.
-jpath pathname Uses pathname as the path for log files instead of the current directory.
-nmake arg Provides the argument, arg, to pass to nmake.exe.
-clean Causes all existing binary built output to be erased and rebuilt.

Special Files

File name Description
build.dat When you use the build utility, it looks for a sources file and a dirs file. It processes the dependencies and builds a file called build.dat. Build.dat is basically a dump from the build utility of what the dependency graph looks like.
dirs You can instruct the build utility to recursively build an entire source tree by using the dirs file. The dirs file resides in a directory that contains subdirectories (that is, at the root of a source code tree or subtree). Each subdirectory can be a source directory or another source tree. Place a dirs file at the root of each source code subtree. Then go to the leaf node in each source code subdirectory and specify the build products in a sources file.

You should define the following macros in your dirs file:

DIRS This macro lists the directories that the build utility should always go into. Specify a list of subdirectories to be built unconditionally. Separate the entries in this list with spaces or tabs
OPTIONAL_DIRS This macro lists the directories that the build utility does not have to go into, and by default will not go into. Specify a list of subdirectories to be built only if they are explicitly specified on the original build command line.
makefile.def The build utility makes use of a generic makefile called makefile.def, which contains all the macro definitions that the sources file uses. The build utility sets the appropriate header and library include paths, compiler names and switches, and linker switches that are defined in makefile.def, and invokes nmake.exe.
makefile.plt The platform-specific information for the makefiles is contained in makefile.plt. You can include makefile.plt in your own makefiles to select the build target and set platform-specific variables.
sources You describe build products in a file named sources that resides in each source code subdirectory. The sources file contains a series of macro definitions that are recognized by the build utility.

Environment Variables

Environment variable Description
BUILD_ALT_DIR Use this to specify an alternate object directory name. It must be ten characters or fewer and contain no spaces. The value is added to the end of the .obj name and (if no -j switch is used for build.exe) the logfile name.
If you do not set this, the default is nothing. Use this macro when you want to build the same source in different console windows using different language, optimizations, or debugging information.
BUILD_DEFAULT_TARGETS Use this to specify the default target platform for which you are building. Usually, you can just set it to the platform you are hosted on, such as build -x86
BUILD_DEFAULT Use this to specify options to build. For example:
 

c:\> build -eswM -nmake -i

is equivalent to:

c:\> set BUILD_DEFAULT=-eswM -nmake -i
c:\> build

BUILD_MAKE_PROGRAM Use this to specify the make program to execute. The default is nmake.exe, which is the only make tool designed to build the SSCLI source tree.
BUILD_OPTIONS Use this to specify the OPTIONAL_DIRS to process. For example:


// DIRS file:
DIRS=dir1 dir2 dir3
OPTIONAL_DIRS=OptDir1 OptDir2 OptDir3

c:\> build OptDir1 OptDir2 OptDir3

is equivalent to:

c:\> set BUILD_OPTIONS=OptDir1 OptDir2 OptDir3
c:\> build

Macro Definitions

Set the variables for most of the following macros in a sources file; a few are set in your environment (for a list of these, see Environment Variables). Except for DIRS and OPTIONAL_DIRS, which are used by the build utility, these macros are all used by nmake.exe. The build utility simply opens all the files, determines the dependencies, and calsl nmake.exe. The other macros used in the build process are all used by nmake. The following table lists the macro names, how they are used, and why you would want to put them in your sources file.

Macro Description
INCLUDES Use this macro in your sources file to indicate to the build utility where to find the headers that you are including in your build. Specify a list of the paths to be searched for include files during compilation. Separate the entries in this list with a semicolon. Path names can be absolute or relative. For example:

INCLUDES=bunny;inc
INCLUDES=.\
INCLUDES=.\inc

The build utility reads the INCLUDES variable that you specify in your sources file to figure out where to find the header files that you are including in your source code so it can build the dependency tree.

Specify header files that do not exist but might be built as part of the build process in USER_INCLUDES.

SOURCES The SOURCES macro is the most important macro for the build utility. You must have this macro in your sources file. The SOURCES macro specifies which files are going to be compiled. The build utility will look at these files and generate a dependency list. If any of those dependencies change, the build utility will rebuild this source file.

Use this macro to list your source filenames (except for the file containing main. Include the filename extension and separate the entries in this list with spaces or tabs.

TARGETLIBS Use this macro to specify other libraries that you want to link against when building your image. This macro should be the primary method you use to specify the libraries or objects that you want to link against to build your image.

TARGETLIBS Paths
Paths specified in TARGETLIBS must be absolute. Separate the entries in this list with spaces or tabs.

For example:

TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\advapi32.lib \
$(SDK_LIB_PATH)\user32.lib \
$(SDK_LIB_PATH)\spoolss.lib

The TARGETLIBS path names must be defined in a special way. Because the build utility can create build products for several hardware platforms, the destination path for build products is constructed as follows:

%TARGETPATH%\<cpu_type>\

where TARGETPATH is defined in the sources file, and cpu_type specifies the platform for which the products were built.

For example, if TARGETPATH is defined as LIB and a build request is made for an x86 processor, the build products will be directed to the following subdirectory:

lib\i386\

Because of this convention, TARGETLIBS entries must specify library names in the following form:

<targetpath>\*\<library_name>

where targetpath is identical to the value assigned to TARGETPATH in the sources file, and library_name is the full file name of the library to be linked to the executable file. The build utility replaces the asterisk (*) with the target platform type.

LINKLIBS and UMLIBS
You can also use the LINKLIBS macro to specify the libraries that you need to link against. This macro is needed for some DLL builds, but it must be used carefully. For more information, see its reference page.

Use LINKLIBS only for the case that meets the following conditions:

  • You are building a dynamic link.
  • You are exporting something that is defined in some other component library that you also build.
  • In your dirs file in the subdirectory above, you have ordered it so that the component libraries are built before you build the dynamic link.

There is a similar macro called UMLIBS that you can use if you are building UMAPPLs.

TARGETEXT Use this macro to specify the extension name (such as .cpl) when you want the DLLs to have something other than .dll as the filename extension.

If you specify something unexpected, you will see a message "Unexpected Target Ext."

TARGETNAME Use this macro to specify the name of the library being built, excluding the filename extension. You must have this macro in your sources file.
TARGETPATH Use this macro to specify the target directory name that is the destination of all build products ( such as .exe, .dll, and .lib files). Notice that object files always end up in the obj subdirectory. You must have this macro in your sources file. For example:

TARGETPATH=obj

TARGETTYPE Use this macro to specify the type of product being built. TARGETTYPE gives the build utility clues about some of the input files that it should expect. You must include this macro in your sources file.The valid values for TARGETYPE include:

PROGLIB - Executable program that also exports functions for other programs.

PROGRAM - User-mode program that does not export anything.

DYNLINK - Dynamic-link library (DLL). This could be a control panel program or anything that can be dynamically loaded.  The DLL switch is passed to the linker to indicate it is not a stand-alone .exe file. When you build a dynamic link, you might also need to set the TARGETEXT macro.

LIBRARY - Import library containing code that will be linked with other code. This is a library of objects, not an import library. (An import library is built as a side effect of building a dynamic link. Anytime you build a dynamic link, you get a .lib file and a .dll file. When you build a library, you just get a .lib file.)

Optional Macros

Macro Description
BASEDIR Use this macro when referring to the base of the source tree. By default, the source tree starts at $(_NTDRIVE)\nt, but this is not required. By using BASEDIR to refer to the base you eliminate hard-coding a specific path.
BINPLACE_FLAGS Use this macro to specify arguments that you want to pass to the Build Output Manager. Type binplace-? to display a list of these switches.
BINPLACE_PLACEFILE Use this macro to specify the placefile used by the Build Output Manager. If nothing is listed,

$(BASEDIR)\public\sdk\lib\placefil.txt

is used by default.

For more information, see binplace.exe.

C_DEFINES Use this macro to specify switches you want passed to the compiler. Typically, they are compiler #define directives.

 You might specify:


C_DEFINES = /DDEBUG_BUILD


to define DEBUG_BUILD to the compiler. There is no limit to what this #define can be except that C_DEFINES gets passed to the compiler and it also gets passed to the resource compiler. Therefore, you cannot put compiler optimization or other processor-specific or tool-specific switches in the C_DEFINES macro. Instead, use one of the following macros for this:

  • MSC_OPTIMIZATION
  • MSC_WARNING_LEVEL
  • USER_C_FLAGS
COFFBASE Use this macro to specify the name to look up in COFFBASE_TXT_FILE. If you do not specify a name, it defaults to the value of TARGETNAME (if you are building a DYNLINK) or usermode (if you are building a UMAPPL, PROGLIB, or PROGRAM). If you want to specify an absolute base address for your image and not use a global file for all, see DLLBASE or UMBASE.
COFFBASE_TXT_FILE Use this macro to specify the name of the file that contains the base addresses for the images you build. By default, this is %ddkroot%\bin\coffbase.txt. If a different file is specified in this macro, the contents of this file will be passed to the linker The file should have three columns. The first is the name of the image. The second is the starting address for the image. The last is the maximum size of the image. There should also be an entry with the name "usermode" that is the default value. For example:

usermode 0x60000000 0x20000000
MyDll1 0x70000000 0x00010000
MyDll2 0x70010000 0x00010000

The build utility assumes that coffbase.txt will be in \\public\sdk\lib and will be called coffbase.txt. You can override this filename and call it anything you want by using COFFBASE_TXT_FILE.

COMPILER_WARNINGS Use this macro to specify the name of the file that contains warning information. By default, this is $(SDK_INC_PATH)\warning.h. If a different file is specified in this macro, the name of this file will be passed to the compiler with the /FI switch. The file contains a list of compiler options used to disable, enable, or promote warnings for the entire build.
CRT_INC_PATH Use this macro to specify the path to the C runtime headers. The default is $(BASEDIR)\public\sdk\inc\crt.
CRT_LIB_PATH Use this macro to specify the path to the C runtime libraries. The default is $(BASEDIR)\public\sdk\lib\*
DEBUG_CRTS Use this macro to specify which set of C runtime libraries should be used.

DEBUG_CRTS=1

DLLBASE Use this macro to set the base address for the DLL image that you are creating. You only need to use this macro when you are building a DLL (that is, when your TARGETTYPE macro is set to DYNLINK).

You can override the default address by specifying an address with the DLLBASE macro (for example, 0x04000000). You can set DLLBASE to be the hard-coded base address or a hexadecimal address.

If DLLBASE is omitted or left blank, the build utility will assume that the target name in coffbase.txt is the name of your image. It will take the value of COFFBASE, if defined, as a key; otherwise, it will take TARGETNAME as a key. The target name in coffbase.txt plus this key will be used to choose the base address.

DLLDEF Use this macro to specify the name of the .def file that the build utility will pass to the librarian when building the export and import files.

If you do not set this value, the build utility will assume it is the same name as the image you are building (in other words, equal to $(TARGETNAME).def).

The most common usage is:

DLLDEF=mydll.def

Additionally, there is a standard inference rule that will run the C preprocessor over the .def or .src file in the current directory to create build-specific .def files in the object subdirectory. The same compiler define directives that you key off of in your source code can be used in the root .def or .src file to create the export list. To enable it, use something like:

DLLDEF=$O\mydll.def

DLLENTRY Use this macro to specify the DLL entry point. By default, no entry point is assumed. For example, when you bring over programs that were built in the Visual C++® build environment or that use the C runtime, you will probably set:

DLLENTRY=_DllMainCRTStartup

DLLLIBOBJECTS Use the DLLLIBOBJECTS macro to specify extra objects to add to an import library.

Usually, when the TARGETTYPE is DYNLINK, the end result is a DLL and an import library. If you want to have different LIB objects for each platform, you can override this value to create different platform-specific DLL LIB objects. DLLLIBOBJECTS enables you to specify additional objects to add to the import library.

For example, you might have an OLE custom control (with GUIDs used to identify this control) that also exports a non-OLE C interface from an import library. Rather than build two separate libraries (for example, mydll.lib and myuuid.lib), you can list the GUID data object(s) in DLLLIBOBJECTS. The result is a single library that your users will link against.

DLLORDER Use the DLLORDER macro to specify an order file that will be passed to the linker when you are building a DLL.

The order file lists the functions and the order in which they should be linked together. By default, the build utility passes the name of the DLL as the name of the order file. For example, if you are building kernel32.dll, the build utility expects kernel32.prf as the order file.

You can use the DLLORDER macro to specify another name. The build utility will use whatever name you give it. It can be in a different subdirectory, have a different name, or have a different extension. You can set DLLORDER to whatever you want it to be, and you can give it a fully qualified path name.

This macro can be used instead of NTPROFILEINPUT.

DRIVERBASE Use this macro to specify the base address for a driver. This macro is similar to the DLLBASE and UMBASE macros. It is not generally necessary to set this value, because it will be relocated at run time.
FREEBUILD Use this macro to specify whether your build is checked (debug) or free (retail). This macro can be used in statements of the form:

If $FREEBUILD (do things for a retail build)

LANGUAGE Use this macro to specify the language when you set up dependencies so that you can include country/region-specific parts in your build.
LINKER_FLAGS Use this macro to override any default linker switch that you want to pass to the linker. Type link-? to view a list of all the linker switches. This macro just gives you a way to pass in flags that you cannot pass in another way.
LINKER_NOREF Use this macro to turn off switches to the linker. The build utility turns some switches on, by default. One of them is the OPTICAL_AND_REF switch, which says, "Throw out everything that is not referenced in this module."
LINKLIBS

Use this macro to specify the libraries that you need to link against.

The only difference between TARGETLIBS and LINKLIBS is the ordering on the command line. LINKLIBS usually gets passed first; TARGETLIBS gets passed second. If you order them correctly in your TARGETLIBS macro, that should not be a problem, except when you are building a DLL.

When you are building a DLL, you could be using objects that you have built in combination with libraries from which you would like to export certain features. For example, perhaps you compile a number of objects into a library in subdirectory one. In subdirectory two, you compile other objects into a library. And in subdirectory three, you build the DLL. However, this DLL must export functions that are defined in library one or library two. In such a case, you must put those libraries in your LINKLIBS macro.

This operation must be carefully done. The LINKLIBS macro requires that the library must be located in pass one of the build, because the build utility builds the import libraries during pass one. You must structure your build in such a manner that the libraries are guaranteed to exist during pass one. You should never specify an import library in your LINKLIBS macro, primarily because you could end up exporting something that you imported from somebody else instead of what you actually had intended (perhaps with syntax errors or other problems). Problems resulting from such a mishap can be undetectable for some time.

As a result, it is almost always better to use TARGETLIBS. Use LINKLIBS only for cases that meet the following conditions:

  • You are building a dynamic link.

  • You are exporting something that is defined in some other component library that you also build.

  • In your dirs file in the previous subdirectory, you have ordered it so that the component libraries are built before you build the dynamic link.

There is a similar macro called UMLIBS that you can use if you are building UMAPPLs.
 

MAKEDLL Use this macro to control whether any actual linking occurs.

Normally, the build process is a two-pass build. In the first pass, the build utility compiles all the source files, and creates import libraries and component libraries. In the second pass, it links everything against those libraries. The default, which directs the build utility to make the second pass, is as follows:

MAKEDLL=1

Typically, you do not set this value. You might do a test in your make file to instruct the build utility:

IF MAKEDLL=1
do things that you want to do on the second pass of the build

A more frequent use of this macro is to run NMAKE from the command line to run the compile and to link without running the build utility:

nmake MAKEDLL=1

The build utility will complete the compile operation and the link in one step without running the build utility. This works because the build utility is only required to determine the dependencies and call NMAKE. This method works when:

  • You know the dependencies.
  • The source file has changed and you do not care about the header file dependency generation.
  • You are in a leaf node subdirectory.
MASTER_VERSION_FILE Use this macro to specify the file name of a master version file.

Every binary file created by the build utility has a version number on it. These are usually based on version resources created by Microsoft when products built for Windows® NT-based operating systems are created.

You can use Windows Explorer or filever.exe to view properties and see which version resource the Setup program uses when it copies that image onto a new system. The system checks whether or not the version resource is newer than the one already on the system. If the resource is newer it is copied onto the system, otherwise it is not copied.

There is a master version file for Windows operating systems, from which all version resources are built. The master version file for Windows operating systems is called ntverp and it is located in %ddkroot%\inc\wxp.

If you do not wish to use the version specified in ntverp, you can specify a different master version file by setting MASTER_VERSION_FILE to the correct file name.

If you look at the very last line of makefile.def, you will see the one place where MASTER_VERSION_FILE is used as a dependency for the resources. The TARGET_DIRECTORY macro is always dependent on the master version file to determine the name of the resource for your image.

MISCFILES Use this macro to list items that you want to put into the appropriate installation point when the build utility runs binplace.exe.
MSC_OPTIMIZATION Use this macro to override the default optimization the build utility uses on the compiler. By default, everything is optimized. If you want to turn off optimization to step through your code, you can set MSC_OPTIMIZATION to whatever is appropriate for your compiler.
MSC_WARNING_LEVEL Use this macro to set the warning level to use on the compiler. The default is W3
NOLINK The NOLINK and MAKEDLL macros are primarily used in the master make file (makefile.def) to indicate which rules to enable or disable when the build utility goes through two tools.

NOLINK=1 indicates that a link is not supposed to occur, most likely because this is pass one and the build utility cannot guarantee that the libraries needed are built yet.

MAKEDLL=1 indicates that a link should occur and is used in pass two after the libraries are built. If you run a one-pass build (by specifying -z on the command line to the build utility), only MAKEDLL=1 is specified.

You can test for this macro in your make file. For example, if NOLINK=1, you are in pass one; if MAKEDLL=1, you are in pass two.

NT_UP Use this macro to indicate whether your driver will run on a uniprocessor computer or multiprocessor computer. The default is uniprocessor, as follows:

NT_UP=1

To specify multiprocessor, set:

NT_UP=0

NTNOPCH Use this macro to turn off the precompiled headers option for a single source file.

If you have precompiled headers on a subdirectory, the build utility expects you to build that subdirectory and to make subsequent changes as you go along. Whenever you change one of the source files, you must rebuild that file. The build utility detects the use of precompiled headers and compiles that single source file without them.

If you set:

NTNOPCH=1

it enables you to build everything, and then to change a definition in a header file (for example, a #define something to something else). Then you can change the source file to use that new definition. Of course, you do not want to regenerate the precompiled header and rebuild everything else; it is preferable to rebuild that one source file, without using the old precompiled header. This macro tells the build utility to turn off precompiled headers for this source file.

The build utility will reread all the headers and use the new header information. This also requires using the -Z or -z command-line options, so that the build utility will not scan dependencies and therefore will not regenerate the precompiled header.

NTTARGETFILE0 You can define the NTTARGETFILE0 and NTTARGETFILES macros to cause makefile.def to include makefile.inc immediately after it specifies the top-level targets (all, clean and loc) and their dependencies.

The makefile.def file expands NTTARGETFILE0 as the first dependent for the all target, and NTTARGETFILES as the last dependent for the all target. Use this macro to specify additional targets and dependencies that do not fit the general case covered by makefile.def.

NTTARGETFILE0=

The fact that NTTARGETFILE0 exists, even if it is defined and empty, causes the build utility to open makefile.inc in the same subdirectory as the sources file.

If you set NTTARGETFILE0 to equal a file name, the build utility will not only include makefile.inc, but will also build the executable that the macro defines. Thus, if you set:

NTTARGETFILE0=myfile.a

then the build utility builds myfile.a as part of pass zero.

If you do not set NTTARGETFILE0, the build utility locates the specified subdirectory on pass zero, includes the makefile.inc in that subdirectory, and follows any default rules that this file contains.

NTTARGETFILE1 This macro is exactly like NTTARGETFILE0, except that it occurs later in the build process. NTTARGETFILE0 occurs on pass zero; NTTARGETFILE1 occurs on pass two.

Both of these macros cause the build utility to change directories to a specified subdirectory and to run nmake.exe on pass zero or pass two in a case where it ordinarily would not do so.

NTTARGETFILES If you have unique rules in your subdirectory, you can use the NTTARGETFILES macro to signal to the build utility that you have a makefile.inc file in addition to the sources file in the subdirectory.

The makefile.inc file will provide additional information about the build process, including dependencies, command line rules, and other build rules.

O Use this macro to specify the final objects subdirectory. Define this macro in your sources file or in makefile.inc to ensure something goes into the object subdirectory. The benefit of using $(O) is that any files that you have built and placed in the objects subdirectory will be deleted on the next clean build. This guarantees that no collisions will occur between two builds running on the same computer at the same time. The builds will never override each other's files if you follow the convention that everything you build goes in $(O).
PASS0_CLIENTDIR Use the PASS0_CLIENTDIR, PASS0_HEADERDIR, and PASS0_SERVERDIR macros when you have a SOURCES macro in your sources file. That macro can contain the following types of files:
  • C
  • C++
  • RC
  • MC
  • IDL

Use the PASS0_CLIENTDIR, PASS0_HEADERDIR, and PASS0_SERVERDIR macros to specify a directory location for the output from the MC and the Microsoft® IDL Compiler (MIDL).

If you run MIDL over sources that include interface description language (IDL) files, the build utility generates a server part, a client part, a header, and a default source. Use the PASS0_SERVERDIR and PASS0_CLIENTDIR macros to specify their output location.

Running MC causes the generation of a header file and a source file.. Use the PASS0_HEADERDIR and PASS0_SOURCEDIR macros to specify their output location.

When you are building a MIDL stub, the protocol is remote procedure call (RPC), so you have both what runs on the client side and what runs on the server side. There are stub programs that communicate through RPC to each other. You can override those by default.

PASS0_HEADERDIR Use this macro to specify the output location of the headers generated by MC and the Microsoft IDL Compiler (MIDL). By default, everything built in pass zero is output to the TARGETPATH subdirectory. Use this macro to change that default.

To create the headers in the current subdirectory, set PASS0_HEADERDIR to dot ("."):

PASS0_HEADERDIR=.

Headers can be output to any location. If your #include directives do not specify the correct location, however, the tools later used by the build utility will not be able to find the headers.

PASS0_SERVERDIR Use this macro to specify an output location for the server part that the Microsoft IDL Compiler (MIDL) generates. By default, the results of pass zero are output to the TARGETPATH subdirectory. Use this macro to change that default.

To create the server part in the current subdirectory, set PASS0_SERVERDIR to dot ("."):

PASS0_SERVERDIR=.

Headers can be sent to any location. If your #include directives do not specify the correct location, however, the tools later used by the build utility will not be able to find the headers.

PASS0_SOURCEDIR Use this macro to specify the sent location for the source code generated by the Microsoft IDL Compiler (MIDL) and maketype.lib file. By default, the results of pass zero are sent to the TARGETPATH subdirectory. Use this macro to change that default.

To create the source code generated by MIDL and maketype.lib in the current subdirectory, set PASS0_SOURCEDIR to dot ("."):

PASS0_SOURCEDIR=.

Your source code and maketype.lib file can be sent to any location. If your #include directives do not specify the correct location, however, the tools later used by the build utility will not be able to find the correct files.

PRECOMPILED_CXX Use this macro to indicate whether the precompiled header you are building will be used with files written in C or C++.

The default is to use precompiled headers with files written in C. Therefore, you should not set PRECOMPILED_CXX if your project will use the precompiled header with files written in C.

To use the precompiled header with C++ files, specify

PRECOMPILED_CXX=1

PRECOMPILED_INCLUDE Use this macro to specify the name of the precompiled header. For example, if you have precompiled headers that are a.c, b.c, and c.c as your source files, and all of them include precomp.h, specify:

PRECOMPILED_INCLUDE=precomp.h

If you omit this instruction, you will not be able to use precompiled headers. PRECOMPILED_INCLUDE sets the build process to use precompiled headers.

PRECOMPILED_OBJ Use this macro to override the default name given to the precompiled object.

By default, the build utility takes the precompiled header with the precompiled #include directive that you specify (for example, precomp.h). The build utility generates precomp.obj for the precompiled object and precomp.pch for the precompiled target.

You can override those names by setting the PRECOMPILED_OBJ and PRECOMPILED_TARGET macros.

PRECOMPILED_TARGET Use this macro to override the default name given to the precompiled target.

By default, the build utility uses the precompiled header with the precompiled #include setting that you specify (for example, precomp.h). The build utility uses the precompiled header to create precomp.obj for the precompiled object and precomp.pch for the precompiled target.

You can override those names by setting the PRECOMPILED_OBJ and PRECOMPILED_TARGET macros.

SDK_INC_PATH Use this macro to specify the path to the SDK headers. The default is:

$(BASEDIR)\public\sdk\inc

SDK_LIB_PATH Use this macro to specify the path to the platform SDK libraries. The default is:

$(BASEDIR)\public\sdk\lib\*

SOURCES_USED Use this macro to indicate that there is another sources file or make file elsewhere in the tree. Use this macro if that additional file contains build dependencies.

When you specify:

SOURCES_USED=filename_someplace_else

Nmake.exe regenerates the objects file when changes occur in the sources file that resides in the specified directory. Nmake.exe will also regenerate the objects file when changes occur in any sources file or make file that you specified in the SOURCES_USED macro.

For example, a sources file typically includes some other file. Just beneath that directive you could specify:

SOURCES_USED=that_filename

This instruction establishes a link between that file and the sources file. When that other file changes, NMAKE regenerates the _objects.mac file.

TARGET_CPP Use this macro to specify the name of the compiler. 

For example, instead of having to specify that on x86 the compiler is CL386, on MIPS it is CLMIPS, and on PowerPC it is CLPPC, you can specify:

TARGET_CPP=name_of_compiler

TARGET_DIRECTORY Use this macro as follows to specify the target directory, if you want some dependency file to always end up in the obj subdirectory:

TARGET_DIRECTORY=some_sourcefile:some_dependency_file

This instruction enables you to draw upon resources contained in a single source tree to complete multiple platform-specific builds without conflicts. You do not have to hard-code the name of the platform.

For example, if you have a special build utility rule for some feature in your code, or if you want to build a particular object from a particular C file, you can use the following line in a sources file:

obj\$(TARGET_DIRECTORY)\filename.obj; filename.c

Using the TARGET_DIRECTORY macro ensures that the specified file will be placed in the appropriate subdirectory. For example, \obj\i386subdirectory\obj\.

There are some default targets. One of them is .cod. If you issue the following instruction from a subdirectory containing source files:

nmake SOURCE_FILE_NAME=.cod

it will create an assembler listing that you can review to determine the location of the compiler error.

There is another default target called .pp file, a preprocessed listing. Preprocessing adds line numbers. You can use these line numbers to determine whether the build utility retrieved headers from the correct location, and which #define directives and structures it added.

If you issue the following instruction from a subdirectory containing source files:

nmake SOURCE_FILE_NAME=.pp

the build utility will preprocess the file.

The .cod and .pp files are very useful for tracking bugs in the build process.

TARGETPATHLIB Use this macro to specify where to put the import library when you are building a DLL.

When you are building a DLL, you create the DLL itself and you create an import library that other images can use that need to use your DLL. For example, a Windows NT developer built kernel32.dll and also kernel32.lib which users of kernel32.dll would link against. In the past you would handle all that by specifying:

TARGETPATH=publicsdk.lib

and it would put both the DLL and the import library in the public tree. By specifying TARGETPATHLIB, you can say, "Put the library in the public tree." Then set TARGETPATH=obj and build uses the DLL in the obj subdirectory in the source tree and put the import library in the public tree.

UMAPPL This macro enables you to build multiple targets from a single subdirectory. If you use UMAPPL, the build utility will automatically build executable files. Listing the names of executables in the build utility command line is unnecessary.

To use this macro, specify a list of source filenames containing a main function. Specify these filenames without filename extensions and separate them with an asterisk. For example:

UMAPPL=a*b*c*d

The build utility will compile and link each file in this list after the main target in the sources file is built. The only restriction is that there can only be one source file and you must specify what it links to using the UMLIBS macro.

The build utility links against whatever things you list in the UMLIBS macro. These could be a .res file if you have a common resource, a library that you just built in a subdirectory, or a library or object from another subdirectory. There is no limit to what can be listed in UMLIBS.

UMAPPLEXT Use this macro to specify the file extensions for image files built from a single source file. The default is .exe. Use UMAPPLEXT when you want the extension to be something other than .exe. (for example, .com or .scr). If you want the file extension to be .exe, use UMAPPL.
UMBASE Use this macro when you are building a dynamic link library. Use it to set the base address for the image you are creating. If you do not specify an address, the build utility will assume that the target name in coffbase.txt is the name of your image. You can override this default target name by specifying a target name with the DLLBASE macro. You can set DLLBASE to be the hard-coded base address or a hexadecimal address, or you can leave it blank. If you leave it blank, the build utility will always look up the target name specified in coffbase.txt.

For example, if you are building kernel32.dll, the build utility will look up kernel32 in coffbase.txt to find that base address.

UMENTRY Use this macro to override the default entry point (mainCRTStartup) and specify the entry point depending on the UM Type. You can set this name to be anything you choose. If the UM Type is Windows or Console, the default entry point is main and you can override it with winmain, wmain, or wwinmain.
UMENTRYABS Use this macro to specify an absolute entry point. For example, you might specify:

UMENTRY=main

However the real entry point is mainCRTStartup. If you do not want mainCRTStartup to be the entry point, specify UMENTRYABS to make main the absolute entry point. This prevents the build utility from going through the translation table.

UMLIBS Use this macro to specify a list of library path names to be linked to the files that are specified in UMTEST or in UMAPPL. Include the library that is generated by the sources file.

The specified paths must be absolute. Separate the entries in this list with spaces or tabs.

The UMLIBS path names must be defined in a special way. Because the build utility can create build products for several hardware platforms, the destination path for build products is constructed as follows:

%TARGETPATH%\<cpu_type>\

where TARGETPATH is defined in the sources file, and cpu_type specifies the platform for which the products were built.

For example, if TARGETPATH is defined as LIB and a build request is made for an x86 processor, the build products will be directed to the following subdirectory:

lib\i386\

Because of this convention, UMLIBS entries must specify library names in the following form:

<targetpath>\*\<library_name>

where targetpath is identical to the value assigned to TARGETPATH in the sources file, and library_name is the full file name of the library to be linked to the executable file. The build utility replaces the asterisk (*) with the target platform type.

UMTEST Use this macro to list source filenames containing a main function. Type these filenames without filename extensions and separate them with an asterisk.

UMTEST=a*b*c*d

The build utility compiles and links each file in this list.

UMTYPE Use this macro to specify the type of product being built
USE_CRTDLL The USE_CRTDLL, USE_MSVCRT, USE_LIBCMT, USE_LIBCNTPR, USE_NTDLL, and USE_NOLIBS macros indicate which run-time libraries the build utility should use.

You should define exactly one of these macros equal to one in your sources file. The other ones should not be defined at all (you cannot define them equal to zero or equal to "").

The different libraries specified by these macros are as follows:

  • USE_CRTDLL                      
    • Use the multi-threaded run-time libraries in a DLL. In the free build environment, this means msvcrt.lib. In the checked build environment, this means msvcrtd.lib.
  • USE_MSVCRT
    • Same as USE_CRTDLL.
  • USE_LIBCMT
    • Use the multithreaded static libraries.
  • USE_LIBCNTPR
    • Use the kernel run-time libraries.
  • USE_NTDLL
    • Use ntdll.dll (the DLL for Windows NT-based operating systems).
  • USE_NOLIBS
    • Do not use any run-time libraries.

If none of these macros are defined, the default behavior is to statically link to the single-threaded run-time libraries. In the free build environment, this means libc.lib. In the checked build environment, this means libcd.lib.

USE_INCREMENTAL_LINKING Use this macro to direct the build utility to use incremental linking.

USE_INCREMENTAL_LINKING=1

Using incremental linking can speed up builds on slower hardware.

USE_NATIVE_EH Use this macro if you are using standard C++ exception handling (try, catch, and throw). Specify the following in your sources file:

USE_NATIVE_EH=1

This instruction directs the build utility to turn on some required compiler switches.

USECXX_FLAG This macro enables you to go to a subdirectory that has all C files and compile them with the C++ compiler rather than the C compiler. (You might want to do this if you have decided to switch to C++.)

Rather than manually change all your file names to a.cpp, b.cpp, you can specify:

USECXX_FLAG=/Tp

This switch directs the compiler to use the C++ compiler rather than the C compiler to compile the specified subdirectory.

USER_C_FLAGS Use the USER_C_FLAGS macro to specify flags that should only be sent to the C/C++ compiler.

Unlike C_DEFINES, USER_C_FLAGS is not sent to the RC compiler.

USER_INCLUDES Use the USER_INCLUDES macro to specify header files that are created during the build process.

Normally, you use the INCLUDES macro in your sources file to indicate the location of your build headers.

There are times, however, when this macro will not be useful because some header files might not exist. For example, some header files are built as part of the build process.

Use the USER_INCLUDES macro to specify header files that are created during the build process. The build utility will search for these header files, will not consider it an error if the files are not found and will not perform dependency checking on them.

Multiprocessor Build Issues

When the build utility is run on a multiprocessor computer, different build utility threads might be running on different processors. Therefore, you should be careful that your products are built in the correct order.

The following macros can be used in your sources files to control the order of the build:

Use SYNCHRONIZE_BLOCK when you have a subdirectory that other subdirectories require the results from in order to build (for example, a global precompiled header). List the precompiled directory first in the dirs file, and add SYNCHRONIZE_BLOCK=1 to the sources file. This assures that the subsequent directories that use the precompiled header will not be built until the header is created.

Use SYNCHRONIZE_DRAIN when you have a subdirectory that needs the results from a prior subdirectory on the same pass. For example, when building a DLL, you might have several subdirectories with TARGETTYPE=LIBRARY, where each builds some component. You might have another subdirectory with TARGETTYPE=DYNLINK, where the build utility will build a DLL that exports functions from the component libraries. In such a case, you should set LINKLIBS to the component libraries, make sure the DLL subdirectory is the last in the parent dirs file, and add SYNCHRONIZE_DRAIN=1 to the sources file for the DLL.

Misuse of These Macros
You should use these macros very sparingly, because they completely stall a multiprocessor build when they are encountered. In most cases, the problem is not with the multiprocessor nature of the build, but rather the macros used in the sources file.

A common mistake is using LINKLIBS to specify import libraries when building a DLL. You rarely need to do this. LINKLIBS must exist during pass 1 because the libraries it specifies are used to build the import library for the DLL. However, TARGETLIBS does not need to exist until pass 2, because the libraries it specifies are only used to link the image.

Therefore, you should use LINKLIBS for component libraries only, and use TARGETLIBS for import libraries.

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 instance, some build processes rely on the linker to determine 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 that you specify the full path to each library you use. It will disable any default library lookup that the linker might attempt 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 platform. You can use the BASEDIR macro to take the place of the root of the source tree. You can use DDK_LIB_PATH to refer to libraries that ship as part of the Windows DDK.

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

TARGETLIBS = \
# Note: SDK_LIB_PATH already ends in "\*" so you should no 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 x86, this would be equivalent to:

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, switch 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", using the following command line will build the library:

build -386

If the sources file contains a UMAPPL macro that identifies an executable named "myexe", this command line will also build "myexe". On the other hand, if "myexe" is identified using a UMTEST macro instead of a UMAPPL macro, the following command line must be used to include "myexe" in the build operation:

build -386 myexe

Library creation is not required for programs that consist of a single source file. In such a situation, define the sources file as follows:

  1. Set TARGETNAME and TARGETPATH as if you were going to generate a library.
  2. Set TARGETTYPE to UMAPPL_NOLIB.
  3. Set SOURCES to nothing.
  4. Do not include the TARGETNAME library in UMLIBS.
  5. Specify the source file name using UMAPPL or UMTEST.
  6. Invoke the build utility (specifying the file name, if listed using UMTEST).

The build utility will generate the executable file.

Precompiled Headers

The easiest way to use precompiled headers is to include the following statement in your sources file:

PRECOMPILED_INCLUDE=some_header_file_that_every_source_file_includes

If you are building C++ code, include the statement:

PRECOMPILED_CXX=1

Nothing else is required.

Precompiled headers are put into the directory specified by the O macro. Their default location will be the obj\platform subdirectory. Therefore, they should not collide during simultaneous compilations.


Copyright (c) 2006 Microsoft Corporation. All rights reserved.