Controlling the Build Process with Custom Build Rules

Microsoft Corporation

March 19, 1997

Introduction

The custom build rules have been improved for Visual C++®, Version 5:

Build Rules Implemented as Operating System Batch Files

The batch files, generated during the build process, run your rules and are then deleted. Because the build rules are implemented as batch files, you can use the development environment's build system to perform any action allowed by the operating system's command processor, such as cd, copy, del, md.

Examples

The following operating system command creates a directory if it doesn't already exist:

if not exist ..\lib\x386 md ..\lib\x386 

The following operating-system command clears the read-only file attribute for My.lib:

if exist ..\lib\x386\My.lib attrib -r ..\lib\x386\My.lib 

The ATL COM AppWizard generates a per-file build rule that calls the MIDL compiler for .idl files. Use the ATL COM AppWizard to create a COM project, select the project's .idl file, press Alt+F7 to access the Build Settings dialog, and study the custom build rule that specifies input to and output from the MIDL compiler.

Using Macros and Environment Variables In Build Rules

Predefined macros and environment variables in build rules are useful for two reasons:

Using the Build System's Macros

When you create a project, the development environment's build system predefines several macros that you can use in your build rules. These are easily recognized because they use mixed-case letters (for example, $(TargetPath)). The build system's macros are documented in the Visual C++ 5.0 documentation in the "Macros for Custom Build Commands" topic. The definitions of the defined macros are specific to your project; if you create a project on one computer and it is used on other computers, the definitions are carried with the project.

The macros are understood by both the build process and NMAKE. If you create an NMAKE-compatible .mak file using the Export Makefile command (Project menu), the definitions of the macros that you use in your project are written to the resulting .mak file.

If neither the build system nor NMAKE can find the definition of a mixed-case macro, the operating system's environment variables are searched for a match.

Using Operating-System Environment Variables

Both the build system and NMAKE recognize operating system environment variables if they are wrapped with the dollar-sign syntax that is recognized by NMAKE. For example, use the following syntax to use the LIB environment variable in a build rule:

$(LIB) 

Important   You must specify all environment variables to the build system and to NMAKE in uppercase letters, as shown in the example above. This is required because the build system follows the historic behavior of NMAKE. NMAKE stores the macro definitions for environment variables in uppercase letters.

Environment variables, such as PATH, INCLUDE, LIB, MSDEVDIR, are useful because they are computer-specific. Because the location of important files, such as CL.exe, Link.exe, and Lib.exe, can differ from computer to computer, the use of common environment variables on each computer allow a project to build as expected on different computers. This assumes that the necessary Visual C++ tools have been installed to each computer using Setup.

Managing Environment Variables

For Microsoft® Windows NT® 4.0, environment variables are managed from the Environment tab of the Control Panel's System application. For Microsoft Windows® 95, they are managed by batch files such as Autoexec.bat.

Specifying Environment Variables Using Batch-File Syntax

In limited cases, you can use environment variables that are wrapped with percent-sign syntax, such as %LIB%. This syntax is commonly used in batch files. Neither the development environment's build system nor NMAKE understand the percent-sign syntax and cannot use their own upper-case copies of the environment variables to interpret environment variables so specified. When encountering this syntax, both tools pass the token to the operating system's command processor for interpretation.

Important   You can use this syntax in only the Build command(s) grid control of the Custom Build tab. You cannot successfully use it in either the Output file(s) or the user-defined dependencies grid control of the Custom Build tab.

When Do Custom Build Rules Run?

Custom build rules are run at different times, depending upon whether they are specified on the Custom Build tab, the Pre-link step tab, or the Post-link step tab.

Rules Specified with the Custom Build Tab

Rules entered on the Custom Build tab run only when any input file is out of date with respect to its output file or if the output file doesn't exist.

Rules Specified with the Post-build Step Tab

Rules that you enter into the Post-build step tab run after successful completion of the normal build process, including successful completion of rules entered on the Custom Build tab. No file timestamps are checked.

Rules Specified with the Pre-link Step Tab

Rules that you enter into the Pre-link step tab run between compile and link time. No file timestamps are checked.

Specifying Build Rules That Run Before the Link Process

You can use the Pre-link step tab to specify build rules that run before the link process. This tab is useful for such actions as creating directories or setting file attributes before the link process.

To specify Pre-link steps:

  1. Right-click the appropriate project from the FileView tab of the Workspace window, and then click Settings.

  2. Choose the appropriate project configuration (such as Debug, Release, All Configurations), from the Settings For list.

  3. Select the Pre-link step tab.

  4. Type operating-system batch file commands, environment variables, and build-rule macros into the grid control.

Specifying Build Rules that Run After the Build Process

You can use the Post-build step tab to specify build rules that run after the build process finishes. These rules will run after those specified on other build rule tabs. You can also use this tab to automatically copy an output file to a drop point, generate a mail message reporting that the build has finished, or run a process that doesn't create an output file, such as regsvr32.

For example, if you've used the ATL COM AppWizard to create an ATL project, look at the Build Rules tab and note that the custom build rule generates a dummy file named regsvr32.trg. This dummy output file has, as a dependency, your ATL COM object and fulfills the necessity that rules entered in the Build Rules tab have an output file whose existence or time stamp can be checked before an action can be taken. In this case, the rule registers your ATL COM object with the operating system, should the build process run far enough to create a new version of the object.

The ATL COM AppWizard was written to use this technique before the existence of the Post-build step tab. You could move the regsvr32 /s /c "$(TargetPath)" rule to this new tab and it would run without the necessity of creating a dummy file.

To specify Post-build steps:

  1. Right-click the appropriate project from the FileView tab of the Workspace window, and then click Settings.

  2. Choose the appropriate project configuration (such as Debug, Release, All Configurations), from the Settings For list.

  3. Select the Post-build step tab.

  4. Type operating-system batch file commands, environment variables, and build-rule macros into the grid control.

Specifying Input Dependencies

You can now specify all of the input files to a file, even if the build process doesn't recognize the extension of either an input file or the dependent file.

To specify input dependencies:

  1. Right-click the appropriate project from the FileView tab of the Workspace window, and then click Settings.

  2. Choose the appropriate project configuration (such as Debug, Release, All Configurations), from the Settings For list.

If the file type is one that is not handled by the development environment's build system:

  1. Click the Custom Build tab.

  2. Click Dependencies.

  3. Type all of the input files into the grid control.

If the file type is one that is already handled by the development environment's build system (such as .cpp, .rc, .idl), the Custom Build tab will not display unless you do the following:

  1. Click the General tab.

  2. Check Always Use Custom Build step.

  3. The Custom Build tab appears.

  4. Type all of the input files into the grid control.

Important   If you choose to define custom dependencies for a file type that the build system already handles, such as .c or .cpp files in Visual C++ and .java files in Visual J++™, you are responsible for all of the steps in the related custom process.

How to Debug Build Rules

The development environment supports three easy ways to debug your custom build rules. We've included a couple of "gotchas" if you're stumped.

Gotchas

Here are two details to check: