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 sourcesWhen 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-patternFor example, we might have the rule:
$(JAVA_CLASSES): %.class : %.javaSuppose 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 : %.javaIn 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.
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
Any rule can have a double-colon instead of a single colon, as in the example
%.tcl :: SCCS/s.%.tclThe 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.