Contents:
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:
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.
build [options] [~]directories
The build utility:
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 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. |
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 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 |
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:
|
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:
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 For example:
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:
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:
Because of this convention, TARGETLIBS entries must specify library names in the following form:
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 Use LINKLIBS only for the case that meets the following conditions:
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:
|
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.) |
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,
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:
|
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:
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.
|
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:
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:
|
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:
|
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:
|
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.
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:
Typically, you do not set this value. You might do a test in your make file to instruct the build utility:
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:
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:
|
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:
To specify multiprocessor, set:
|
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:
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.
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:
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:
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 ("."):
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 ("."):
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 ("."):
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_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:
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:
|
SDK_LIB_PATH | Use this macro to specify the path to the platform SDK libraries. The
default is:
|
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:
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:
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_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:
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:
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:
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:
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:
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:
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:
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:
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:
Because of this convention, UMLIBS entries must specify library names in the following form:
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.
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:
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.
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:
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:
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. |
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.
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:
The build utility will generate the executable file.
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.