Writing correct makefiles

This is an alternative method to build Java applications with clearmake.

A correctly written makefile results in a correct set of configuration records, which gives you the full power of HCL VersionVault configuration records and winkin without unnecessary rebuilding and without missing rebuilds. You can restructure a makefile to avoid automatic building behavior of javac by enforcing that files on which other files depend are built before their dependents.

Note: clearmake and omake detect implicit dependencies but cannot determine build order dependencies. If you want files to build in a certain order, you must declare that order in the makefile by adding additional dependencies.

You must take extra care when handling mutually dependent files, because there is not necessarily a correct order for building them. One possibility is to always generate all mutually dependent files as one unit, that is, in one configuration record. You can write the build script for a set of mutually dependent files to delete all class files that correspond to those files before building any of them. This practice ensures that they are not overwritten individually and makes them available as a unit for winkin.

The advantage of writing your makefile correctly is that you avoid extra compilations or rebuilds. No special makefile directives are required, the configuration records have no unusual properties, and winkins work fully. The disadvantage is that the makefile must always be synchronized with the structure and dependencies of the application.

The following sections are makefile examples for applications with particular dependency characteristics.

No mutually dependent files

In this application, classes x, y, and z have a hierarchical dependency graph:

The makefile for such a dependency structure is very simple:

.SUFFIXES: .java .class

.java.class:
   javac $<
x.class: y.class
y.class: z.class

Mutually dependent files

This application consists of classes top, a, b, c, and d, which have a more complex dependency structure:

The makefile for this dependency structure is somewhat longer, but correct:

top.class: a.class b.class
   javac top.java

a.class: b.class

b.class:
     rm -f a.class b.class
     javac a.java b.java

b.class: c.class

c.class: d.class

d.class:
     rm -f c.class d.class
     javac c.java d.java