We sometimes want to build essentially the same system in several different "ways". For example, we want to build `ghc''s `Prelude' libraries with and without profiling, with and without concurrency, and so on, so that there is an appropriately-built library archive to link with when the user compiles his program. It would be possible to have a completely separate build tree for each such "way", but it would be horribly bureaucratic, especially since often only parts of the build tree need to be constructed in multiple ways.
Instead, the `template.mk' contains some clever magic to allow you to build several versions of a system; and to control locally how many versions are built and how they differ. This section explains the magic.
The files for a particular way are distinguished by munging the suffix. The "normal way" is always built, and its files have the standard suffices `.o', `.hi', and so on. In addition, you can build one or more extra ways, each distinguished by a way tag. The object files and interface files for one of these extra ways are distinguished by their suffix. For example, way `mp' has files `.mp_o' and `.mp_hi'. Library archives have their way tag the other side of the dot, for boring reasons; thus, `libHS_mp.a'.
A `make' variable called `way' holds the current way tag. `way' is only ever set on the command line of a recursive invocation of `gmake'. It is never set inside a `Makefile'. So it is a global constant for any one invocation of `gmake'. Two other `make' variables, `way_' and `_way' are immediately derived from `$(way)' and never altered. If `way' is not set, then neither are `way_' and `_way', and the invocation of `make' will build the "normal way". If `way' is set, then the other two variables are set in sympathy. For example, if `$(way)' is "`mp'", then `way_' is set to "`mp_'" and `_way' is set to "`_mp'". These three variables are then used when constructing file names.
So how does `make' ever get recursively invoked with `way' set? There are two ways in which this happens:
%.$(way_)o : %.lhs $(HC) $(HC_OPTS) $< -o $@Neat, eh?