3.3 Accommodating Build Avoidance

When you first begin to build software systems with ClearCase, the fact that omake (or clearmake) uses a different build-avoidance algorithm than other make variants may occasionally surprise you. This section describes several such situations and presents simple techniques for handling them.

Increasing the Verbosity Level of a Build

If you don't understand omake's (or clearmake's) build-avoidance decisions, use the -v (somewhat verbose) or -d (extremely verbose) option. For clearmake you can also set environment variable CCASE__VERBOSITY to 1 or 2, respectively, for equivalent behavior. When clearmake rebuilds a target due to a "build script mismatch," the -v and -d options also return a summary of differences between the build scripts.

Handling Temporary Changes in the Build Procedure

Typically, you do not edit a target's build script in the makefile very often. But you may often change the build script by specifying overrides for make macros, either on the command line or in the Windows NT environment. For example, target hello.obj is specified as follows in the makefile:

hello.obj: hello.c hello.h
del hello.obj
cl /c $(CFLAGS) hello.c

When it executes this build script, omake (or clearmake) enters the build script, after macro substitution, into the config record. The command

Z:\myvob> omake hello.obj CFLAGS="/02 /G5"

produces this configuration record entry:

--------------------------------
Build script:
--------------------------------
cl /c /02 /G5 hello.c

The omake (or clearmake) build-avoidance algorithm compares effective build scripts. If you then use the command omake hello.obj without specifying CFLAGS="/02 /G5", omake (or clearmake) rejects the existing derived object, which was built with those flags. The same mismatch occurs if you create a CFLAGS environment variable with a different value, and then invoke omake (or clearmake) with the -e option.

Specifying Build Options

To manage temporary overrides for make macros and environment variables, place macro definitions in build options specification (BOS) files. clearmake provides several ways for using a BOS file. For example, if your makefile is named project.mk, macro definitions are read from project.mk.options. You can also keep a BOS file in your home directory, or specify one or more BOS files with clearmake -A. For details, see Build Options Specification Files.

To manage these temporary overrides with omake, you can place macro definitions in a separate makefile. To include this makefile, specify the -f makefile option.

Using a BOS file or separate makefile to specify make macro overrides relieves you of having to remember which options you specified for the last build. If you have not modified the BOS or separate makefile recently, derived objects in your view are not disqualified for reuse on the basis of build script discrepancies. Some of the sections that follow describe other applications of BOS files.

Handling Targets Built in Multiple Ways

Because omake (and clearmake) compare build scripts, undesirable results may occur if your build environment includes more than one way to build a particular target. For example, suppose that the target test_prog_3 appears in two makefiles in two directories. The first is in its source directory, util_src:

test_prog_3.exe: ...
cl /Fl test_prog_3.c ...

The second is in another directory, app_src:

..\util_src\test_prog_3.exe: ...
cd ..\util_src & cl /Fl test_prog_3.c

Derived objects built with these scripts may be equivalent, because they are built as the same file name (test_prog_3) in the same VOB directory (util_src). But by default, a build in the app_src directory never reuses or winks in a DO built in the util_src directory, because build-script comparison fails.

You can suppress build-script comparison for this target by using an omake special build target, .NOCMP_SCRIPT, or a clearmake special build target, .NO_CMP_SCRIPT in the makefile or in an associated BOS file:

.NO_CMP_SCRIPT: ..\util_src\test_prog_3.exe (clearmake build target)

.NOCMP_SCRIPT: ..\util_src\test_prog_3.exe (omake build target)

To suspend build-script comparison once, you can use either omake -O or clearmake -O.

Using a Recursive Invocation of omake or clearmake

You can eliminate the problem of different build scripts described in Handling Targets Built in Multiple Ways by adding a recursive invocation of clearmake to the makefile in app_src:

..\util_src\test_prog_3.exe: ...

cd ..\util_src & $(MAKE) test_prog_3.exe

($(MAKE) invokes omake or clearmake recursively)

Now, target test_prog_3 is built the same way in both directories. You can turn on build-script comparison again, by removing the .NOCMP_SCRIPT or .NO_CMP_SCRIPT special target.

Optimizing Winkin by Avoiding Pseudotargets

Like other make variants, omake (or clearmake) always executes the build script for a pseudotarget, a target that does not name a file system object built by the script. For example, in the section Using a Recursive Invocation of omake or clearmake, you may be tempted to use a pseudotarget in the app_src directory's makefile:

test_prog_3.exe: ... (shortened from ..\util_src\test_prog_3)
cd ..\util_src & $(MAKE) test_prog_3.exe

A build of any higher-level target that has test_prog_3.exe as a build dependency always builds a new test_prog_3.exe, which in turn triggers a rebuild of the higher-level target. If the rebuild of test_prog_3.exe was not necessary, the rebuild of the higher-level target may not have been necessary, either. Such unnecessary rebuilds decrease the extent to which you can take advantage of derived object sharing.

Accommodating the Build Tool's Different Name

The fact that the ClearCase build utility has a unique name, omake (or clearmake), may conflict with existing build procedures that implement recursive builds. Most make variants automatically define the make macro $(MAKE) as the name of the build program, as it was typed on the command line:

Z:\avob> make hello.obj

(sets MAKE to "make")

Z:\avob> omake hello.obj

(sets MAKE to "omake")

Z:\avob> clearmake hello.obj

(sets MAKE to "clearmake")

Z:\avob> my_make hello.obj

(sets MAKE to "my_make")

This definition enables recursive builds to use $(MAKE) to invoke the same build program at each level. The section Optimizing Winkin by Avoiding Pseudotargets includes one such example; here is another one:

SUBDIRS = lib util src

all:
for %DIR in ($(SUBDIRS)) do cd %DIR & $(MAKE) all

Executing this build script with omake (or clearmake) invokes omake all (or clearmake all) recursively in each subdirectory.