Makefile documentation


General

I intend to gather here descriptions for rationales for techniques used and choices made in the makefiles.


Top makefile

I made a main makefile at the top of the makefile structure.

This is intended as the point where to build the whole p1tre VOB.

This is however not the place where dependencies between the different targets should be described: the natural place for this would be within every pob's own main makefile.

As this is currently not done, the top makefile cannot be run with parallel building enabled.
For this to work, one needs that the dependencies are:

Otherwise, the task would be first distributed, and only then would the dependencies be evaluated, with the result that they would be multiply evaluated, which would be very inefficient.

The solution lies in producing for each target in the top makefile a DO (i.e. a tag file), whose CR would reflect the actual dependencies.

This in turn requires that the main target in every pob makefile produces a DO, which can be read in the respective rule in the top makefile, thus infact concatenating the CR. This way, the top makefile would access enough of information for the build process to distribute intelligently the tasks.

pob_xxx:
	( cd pob_dir; $(MAKE) tag )
	cat pob_dir/tag > /dev/null
	touch pob_xxx

I made a test implementation of this idea, which frightens me a bit by its complexity. A positive side-effect of it is that the tag files in the top directory will record the dependency upon the makefiles as well.


Makefile components

paths.mak

This file should include all the local configuration info, as makefile macros.

This is however not fully true, since there must be a way to include this very file itself. The schema chosen to minimze the spreading of such information is to use two levels of soft links:

One might consider adding other kind of local configuration information in this file (not only paths).

defs.mak

Makefile definitions may be available lexically before they are being used, i.e. within rules. Therefore, to allow including makefiles to add or modify definitions, these must be separated from the rules.

The last definition met takes precedence.

rules.mak

Note that one cannot override rules.

makedefs

The only former component for inclusion. Kept for backwards compatibility as a wrapper including the two latter.


Main makefile

This designates a makefile meant to be used directly on a clearmake invocation, as opposed to a makefile component to be included.

There is typically one such makefile per directory, named by default Makefile.

There may however be several such main makefiles in a directory, used for instance from the default Makefile in recursive invocations of clearmake.


Remote Dependencies and Parallel Building

If we want to use parallel building, we need to describe dependencies between the targets to be distributed. This will enable clearmake to compute an order between the various builds, and to avoid executing on one node a build script depending on the result of one executed in parallel on an other, and thus possibly non-available at the time when it would be needed.

We inevitably run into the need to describe remote dependencies, i.e. dependencies on remote targets. A work-around is needed to prevent the systematic execution of build script depending on such targets.

This work-around will use pseudo-targets and the special target .NOTPARALLEL.

Instead of having a target $(PROGRAM) depend on the remote target $(PROJDEPS), which would imply that the executable is always linked anew, we can have the pseudo-target all depend in sequence on $(PROJDEPS) and on $(PROGRAM).

This first idea fails however in presence of parallel building: if this is enabled, clearmake could distribute these two (sets of) targets on different nodes, thus possibly linking the program with old versions of the libraries, or failing to link it because the libraries would not have been produced yet.

Thus, either Parallel building must be disabled, or one must recursively invoke clearmake. This way, the subsession may apply build avoidance, thus refraining from building again $(PROGRAM) if unnecessary.

Using .NOTPARALLEL

Setting the special target .NOTPARALLEL unfortunately affects the whole makefile. The preferred strategy is thus to split the makefile in two, thus executing the build script for $(PROGRAM) in a recursive invocation, invoking the makefile in which parallel building is not disabled.

PROJDEPS

This is a macro initialized to empty, but to be redefined in the local main makefiles, to express the external dependencies of a POB.

It corresponds to a remote target, invoking the all target in a remote directory. The reason for building the all target, instead of the actual library (or other), is obviously to evaluate its potential external dependencies.

Tag files and recursive invocation

One small nit with recursive invocation relates with the use of tag files as targets. In such a case, the makefile in its globality gets recorded in the tag file's CR, which leads to useless rebuilds.

Note that this may precisely be the intention, e.g. if one wants to record the makefile for labelling purpose.
But in this case, the rule should not do anything in addition (the subsession itself will anyway go through its own build avoidance step).


Tasks and plans, Installation related issues, Terminology
Marc Girod
Last modified: Fri Mar 17 16:16:28 EET 2000