Chapter 10. Building with clearmake;
Some Basic Pointers

This chapter presents some simple pointers on making best use of clearmake. See the chapters that follow for more detailed discussions.

Accommodating clearmake's Build Avoidance

When you first begin to build software systems with ClearCase, the fact that 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 clearmake's Verbosity Level

If you don't understand clearmake's build-avoidance decisions, use the -v (somewhat verbose) or -d (extremely verbose) option. Equivalently, set environment variable CLEARCASE_BLD_VERBOSITY to 1 or 2, respectively.

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 effective build script by specifying overrides for make macros, either on the command line or in the UNIX environment. For example, suppose target hello.o is specified as follows in the makefile.

hello.o: hello.c hello.h
      rm -f hello.o
      cc -c $(CFLAGS) hello.c

When it executes this build script, clearmake enters the effective build script, after macro substitution, into the config rec. The command:

% clearmake hello.o CFLAGS="-g -O1"
... produces this configuration record entry:
--------------------------------
Build script:
--------------------------------
        cc -c -g -O1 hello.c

So would this command:

env CFLAGS="-g -O1" clearmake -e hello

The clearmake build-avoidance algorithm compares effective build scripts. If you subsequently issue the command clearmake hello.o without specifying CFLAGS="-g -O1", clearmake will reject the existing derived object, which was built with those flags. The same mismatch would be caused by creating a CFLAGS environment variable (EV) with a different value, and invoking clearmake with the –e option.

Using a Build Options Specification (BOS) File

To manage “temporary overrides” specified with make macros and EVs, place macro definitions in build options specification (BOS) files. There are several mechanisms for having clearmake use a BOS file. For example, if your makefile is named project.mk, macro definitions are automatically 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; see the clearmake.options manual page for details.

Using a BOS file to specify make macro overrides relieves you of the burden of having to remember which options you specified last time on the command line or in the environment. If you have not modified the BOS file recently, derived objects in your view will not be disqualified for reuse on the basis of build script discrepancies. Some of the sections below describe other applications of BOS files.

Handling Targets Built in Multiple Ways

clearmake's inclination to compare build scripts may produce undesirable results if your build environment includes more than one way to build a particular target. For example, there might be a test_prog_3 target in two directories:

... in its source directory, util_src:
test_prog_3: ...
      cc -o test_prog_3 ...
... and in another nearby directory, app_src:
../util_src/test_prog_3: ...
      cd ../util_src ; cc -o test_prog_3

Derived objects built with these scripts are potentially equivalent, because they are built at the same file name (test_prog_3) in the same VOB directory (util_src). But by default, a build in the app_src directory will never reuse or wink-in a DO built in the util_src directory, because build-script comparison fails.

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

.NO_CMP_SCRIPT: ../util_src/test_prog_3

For a one-time suspension of build-script comparison, you can use clearmake -O.

Using a Recursive Invocation of clearmake

It is easy to eliminate the different-build-scripts problem described in the preceding section. Figure 10-1 shows the recursive invocation of clearmake.

Figure 10-1. Recursive Invocation of clearmake


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

Changes of this kind may cause unexpected encounters with another clearmake build-avoidance feature, however. Whenever clearmake executes the build script of a lower-level target, it always rebuilds all higher-level targets that depend on it. (Many make variants are not as insistent as clearmake in this regard.) In this example, the execution of the build script for target ../util_src/test_prog_3 may or may not actually build a new test_prog_3; but because clearmake has executed the build script, it will always rebuild a higher-level target that depends on ../util_src/test_prog_3:

TESTPROGS = ../util_src/test_prog_3 ../util_src/test_prog_7
TESTDATA  = test_input.1 test_input.2 test_input.3

test_output: $(TESTPROGS) $(TESTDATA)
	rm test_output
	../util_src/test_prog_3 test_input.1 >> test_output
	../util_src/test_prog_3 test_input.2 >> test_output
	../util_src/test_prog_3 test_input.3 >> test_output

Optimizing Wink-In by Avoiding Pseudo-Targets

Like other make variants, clearmake always executes the build script for a pseudo-target, a target that does not name a file system object built by the script. For example, in the preceding section, you might be tempted to use a pseudo-target in the app_src directory's makefile. Figure 10-2 provides an example of :

Figure 10-2. Build Script Example


A build of any higher-level target that has test_prog_3 as a build dependency will always build a new test_prog_3, which in turn triggers a rebuild of the higher-level target. If the rebuild of test_prog_3 was not really necessary, then 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 ClearCase's derived object sharing capability.

Accommodating clearmake's Different Name

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

% make hello.o           .. sets MAKE to “make”
% clearmake hello.o      .. sets MAKE to “clearmake”
% my_make hello.o        .. sets MAKE to “my_make”

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

SUBDIRS = lib util src
all:
for DIR in $(SUBDIRS) ; do ( cd $$DIR ; $(MAKE) all ) ; done

Executing this build script with clearmake will recursively invoke clearmake all in each subdirectory.

Avoid “breaking” this mechanism by explicitly setting a particular build program in the makefile, or in a BOS file:

MAKE = make

With the above setting, executing the build script above with clearmake would recursively invoke make all (instead of clearmake all) in each subdirectory. Presumably, this would be an error.

Continuing to Work During a Build / Reference Time

clearmake takes into account the fact that software builds are not instantaneous. As your build progresses, other developers continue to work on their files, and may check in new versions of elements that your build uses. If your build takes an hour to complete, you would not want build scripts executed early in the build to use version 6 of a header file, and scripts executed later to use version 7 or 8.

To prevent such inconsistencies from occurring, any versions that were checked in after the moment that clearmake was invoked are automatically “locked out”. The moment that the clearmake build session begins is termed the build reference time.

The same reference time is reported in each configuration record produced during the build session, even if the session lasts hours (or days!) as shown in Figure 10-3.

Figure 10-3. Build Reference Time Report


When determining whether an object was created before or after the build reference time, clearmake automatically adjusts for clock skew, the inevitable small differences among the system clocks on different hosts. For more on build sessions, see “Build Sessions, Subsessions, and Hierarchical Builds”.


Caution: A build's coordinated reference time applies to elements only, providing isolation from “after-the-last-minute” changes to them. You are not protected from changes to view-private objects and non-MVFS objects. For example, if you begin a build and then change a checked-out file used in the build, a failure may result. Thus, don't keep working on the same project in a view where a build is in progress.


Using Config Spec `Time Rules' to Increase Your View's Isolation

Using the reference time facility described in the preceding section, clearmake automatically blocks out potentially incompatible source-level changes that take place after your build begins. But sometimes, the incompatible change has already taken place. ClearCase allows you to “roll back the clock” in order to block out recently-created versions.

A typical ClearCase team-development strategy is to have each user in the team work in a separate view, but to have all the views use the same config spec. In this way, the entire team works “on the same branch”. As long as a source file remains checked-out, its changes are isolated to a single view; but as soon as the user checks in a new version, the entire team sees the new version on the dedicated branch.

This “incremental integration” strategy is often very effective — but suppose that another user's recently-checked-in version has caused your builds to start failing. Through an exchange of electronic mail, you determine that the “killer checkin” was to header file project_base.h, at 11:18 AM today. You, and other team members, can reconfigure your views to roll back just that one element to a “safe” version:

element project_base.h .../onyx_port/LATEST -time 5-Mar.11:00

If many interdependent files have been revised, you might roll back the clock for all checked-in elements:

element * .../onyx_port/LATEST -time 5-Mar.11:00

For a complete description of time rules, see the config_spec manual page.

Overprecise Use of Time Rules

Your view's view_server process interprets time rules with respect to the create version event record written by the checkin command. The checkin is read from the system clock on the host where the VOB resides. If that clock is seriously out-of-sync with the clock on your host (where the view_server runs), your attempt to roll back the clock may fail. Thus, don't strive for extreme precision with time rules: select a time that is well before the actual cutoff time (for example, a full hour before, or in the middle of the night).

Inappropriate Use of Time Rules

Do not use time rules to “freeze” a view to the current time just before starting a build. Just allow clearmake's reference time facility to perform this service automatically. Here's an inappropriate use scenario:

  1. You checkin version 12 of util.c at what is 7:05 PM on your host. You do not know that clock skew on the VOB host causes the time “7:23 PM” to be entered in the create version event record.

  2. In an effort to “freeze” your view, you change your config spec to include this rule:

    element * /main/LATEST -time 19:05
    

  3. You issue a clearmake command right away (at 7:06 PM) to build a program that uses util.c. When selecting a version of this element to use in the build, your view_server consults the event history of util.c and rejects version 12, because the “7:23PM” time stamp is too late for the - time configuration rule.

Problems with `Forced Builds'

clearmake has a - u option (“unconditional”), which forces rebuilds. Using this option reduces the efficiency of derived object sharing, however. If you force-build

a target in a situation where clearmake would have winked-in an existing DO, you create a new DO with same configuration as an existing one. In such situations, a user who expects a build to share a particular existing DO may get another, identically-configured DO instead. This may result in user confusion and wasted disk space.

clearmake tries to minimize the problems by selecting the oldest DO in such situations. With this strategy, most builds will tend to “stabilize” on old objects, rather than picking up newly-built equivalent candidates.

We suggest that you use a flag-file to force a rebuild, rather than using clearmake –u. (See “Explicitly-Declared Source Dependencies”.)

Wink-in, Permissions on Derived Objects, and clearcase_bld_umask

UNIX-level permissions on derived objects (DOs) affect the extent to which they are sharable:

  • When you perform a build, clearmake winks-in a derived object to your view only if you have `read' permission on the DO.

  • clearmake will wink-in a DO to which you do not have `write' permission. But “permission denied” errors may occur during a subsequent build, when a compiler (or other build script command) attempts to overwrite such a DO. (Removing the target before rebuilding it is an easy, reliable workaround; but you may wish to avoid revising your makefiles in this way.)

If you and other members of your group wish to share DOs, make sure that they are created with a mode that grants both `read' and `write' access to group members. To accomplish this, you (and other group members) can use either of the following alternatives:

  • Set your umask value to 2 in your shell startup file.

  • Leave a more restrictive umask value in your shell startup file. (The value 22 is commonly used, which denies `write' rights to group members.) Instead, set environment variable CLEARCASE_BLD_UMASK to 2. The value of this

  • EV temporarily replaces your current umask value during each invocation of clearmake.


    Note: If you wish, you can set CLEARCASE_BLD_UMASK as a make macro, instead of as an environment variable.


Don't worry about the “safety” of your derived objects — using a CLEARCASE_BLD_UMASK that grants `write' rights to group members does not mean that they can overwrite and destroy a derived object that you still are using. If your DO has been winked into another view, and a user in that view actually rebuilds the corresponding makefile target, clearmake first “breaks the link” to your DO, and then provides an actual file in that view for the build script to overwrite.