Changes by: Jason Hickey (jyh at cs.caltech.edu)
Date: 2003-11-16 11:57:21 -0800 (Sun, 16 Nov 2003)
Revision: 273
Log message:
In this version, the source dependencies for implicit targets
are computed lazily. This means that rules like this make sense:
%.cmi: $(if $(target-exists %.mli, %.mli), %.ml)
...
However, I don't know if I like this method because the semantics
are confusing. Since the dependencies are lazy, the dependency
list is evaluated in the context where the rule is instantiated.
For example, this top-level rule does not have the desired effect:
%.cmi %.cmiz: $(MPINSTALL) $(PRLC)
If this rule is instantiated in, say, theories/itt, then
$(MPINSTALL) is bound to theories/itt/mp.install, not the top-level
mp.install as you get with eager evaluation. There is a solution,
which is to force evaluation:
%.cmi %.cmiz: $,(target $(MPINSTALL) $(PRLC))
The $, forces eager evaluation, and the target function fetches
the .PHONY node in the root context.
This seems too complicated--the uniform eager semantics earlier
was easier.
Here is my new proposed solution. First, allow for multiple
kinds of source dependencies.
d ::= exp (* dependencies, eager evaluation *)
| d :lazy: exp (* dependencies, lazy evaluation *)
| d :optional: exp (* optional dependencies, eager *)
| d :exists: exp (* existential dependencies, eager *)
Second, allow computed rules, where the rule body is a function
that computes the actual rule. Evaluation of the rule body is lazy.
%.cmi: %.ml :compute:
if $(NATIVE_ENABLED)
%.cmi %.cmx %$(EXT_OBJ): %.ml
$(OCAMLOPT) ...
else
%.cmi %.cmo: %.ml
$(OCAMLC) ...
For now, I'll leave this branch idle and explore the new option.