Rules

tclmake recognizes rules in a subset of make syntax. The types of rules recognized are:

Simple rules

Simple rules are rules that contain a colon but do not contain a percent sign.

tclIndex: $(TCL_SRCS)

Targets are to the left; dependencies to the right. There can be an arbitrary number of either. Wild-cards, such as *.tcl can be used on either side of the colon.

If a target does not exist, or if any of the dependencies are newer than any of the targets, then that target is out of date, and the command will be executed to update it. If any dependency is itself a target (in another rule), then the dependencies will be chained to determine if the dependency itself needs updating,

Phony targets

If a target is not the name of a file, then it is what is called a "phony target". This allows rules to act almost as procedure calls. For example, a first rule in a tclmakefile may be:

all: tclIndex sources
When tclmake attempts to update the goal all, it looks for a file named all. If it doesn't find one, it recursively attempts to update the dependencies tclIndex and sources. The effect is exactly the same as if tclIndex and sources had been the goals in the first place.

(Unlike regular make, tclmake does not have any means of specifying which targets are phony. The way that phony targets works is somewhat different, but I am not sure yet whether this will cause problems.)

Pattern rules

A pattern rule uses the character % as a place-holder to match patterns. The general form of this rule is:

targets : target-pattern  : dep-pattern 
For example, we might have the rule:
$(JAVA_CLASSES): %.class : %.java
Suppose the hype.class file becomes a goal, then tclmake will match the pattern %.class against it, and use hype.java as its dependency.

More often than not, the initial target list will be omitted, as in:

%.class : %.java
In this case, tclmake will try matching the pattern %.class against any target that becomes a goal. This is less efficient, but often more convenient.

tclmake recognises a special case: the target is supplied, but it matches no target-patterns, or none of the dependencies from matching actually exist. In this case, tclmake does a "reverse" pattern match: it matches the dependency pattern against existing files, and if any files are found, updates the corresponding targets.

For example, the default tclmakefile contains the rule

sources: % :: SCCS/s.%
        exec sccs get $<
The pattern-match will find sources as a target, and SCCS/s.sources as a dependency. Since, however, the latter file does not exist, tclmake pattern-matches against all files in the SCCS directory, with the result that all files with a new SCCS file will be updated.

Suffix rules

A suffix rule consists of two concatenated file suffixes. For example:

.java.class:
A suffix rule is an older form of rule. This rule is equivalent to the rule
%.class : %.java

Double-colon rules

Any rule can have a double-colon instead of a single colon, as in the example

%.tcl :: SCCS/s.%.tcl
The double-colon means that this rule is a terminator rule. tclmake will not chain dependencies in implicit rules. In this example, this means that, if tclmake finds, say, a file foo.tcl, but no file named SCCS/s.foo.tcl, it will not attempt to update a target named SCCS/s.foo.tcl, which can never be a target.

In other words, use the double-colon when a dependency is a file that must exist, and cannot be produced from other files.

Option rules

One of the few extensions tclmake makes to regular make is the ability to define command-line options in the tclmakefile itself. To do so, simply define a rule that has targets beginning with a leading dash, and with no dependencies. If any of those targets are specified on the command line, the rule will be run after updating all other targets.

So far, the only real use I have come up with for this facility is for recursive makes. The --recursive and --packages command-line options are defined in this way. See Recursive tclmakes for examples.